init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class DsaDigestSigner : ISigner
{
private readonly IDsa dsa;
private readonly IDigest digest;
private readonly IDsaEncoding encoding;
private bool forSigning;
public virtual string AlgorithmName => digest.AlgorithmName + "with" + dsa.AlgorithmName;
public DsaDigestSigner(IDsa dsa, IDigest digest)
{
this.dsa = dsa;
this.digest = digest;
encoding = StandardDsaEncoding.Instance;
}
public DsaDigestSigner(IDsaExt dsa, IDigest digest, IDsaEncoding encoding)
{
this.dsa = dsa;
this.digest = digest;
this.encoding = encoding;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter asymmetricKeyParameter = ((!(parameters is ParametersWithRandom)) ? ((AsymmetricKeyParameter)parameters) : ((AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters));
if (forSigning && !asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Signing Requires Private Key.");
}
if (!forSigning && asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Verification Requires Public Key.");
}
Reset();
dsa.Init(forSigning, parameters);
}
public virtual void Update(byte input)
{
digest.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning)
{
throw new InvalidOperationException("DSADigestSigner not initialised for signature generation.");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
BigInteger[] array2 = dsa.GenerateSignature(array);
try
{
return encoding.Encode(GetOrder(), array2[0], array2[1]);
}
catch (Exception)
{
throw new InvalidOperationException("unable to encode signature");
}
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
{
throw new InvalidOperationException("DSADigestSigner not initialised for verification");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
try
{
BigInteger[] array2 = encoding.Decode(GetOrder(), signature);
return dsa.VerifySignature(array, array2[0], array2[1]);
}
catch (Exception)
{
return false;
}
}
public virtual void Reset()
{
digest.Reset();
}
protected virtual BigInteger GetOrder()
{
if (!(dsa is IDsaExt))
{
return null;
}
return ((IDsaExt)dsa).Order;
}
}

View File

@@ -0,0 +1,120 @@
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;
}
}

View File

@@ -0,0 +1,185 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class ECDsaSigner : IDsaExt, IDsa
{
private static readonly BigInteger Eight = BigInteger.ValueOf(8L);
protected readonly IDsaKCalculator kCalculator;
protected ECKeyParameters key = null;
protected SecureRandom random = null;
public virtual string AlgorithmName => "ECDSA";
public virtual BigInteger Order => key.Parameters.N;
public ECDsaSigner()
{
kCalculator = new RandomDsaKCalculator();
}
public ECDsaSigner(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 ECPrivateKeyParameters))
{
throw new InvalidKeyException("EC private key required for signing");
}
key = (ECPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
{
throw new InvalidKeyException("EC public key required for verification");
}
key = (ECPublicKeyParameters)parameters;
}
random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, provided);
}
public virtual BigInteger[] GenerateSignature(byte[] message)
{
ECDomainParameters parameters = key.Parameters;
BigInteger n = parameters.N;
BigInteger bigInteger = CalculateE(n, message);
BigInteger d = ((ECPrivateKeyParameters)key).D;
if (kCalculator.IsDeterministic)
{
kCalculator.Init(n, d, message);
}
else
{
kCalculator.Init(n, random);
}
ECMultiplier eCMultiplier = CreateBasePointMultiplier();
BigInteger bigInteger3;
BigInteger bigInteger4;
while (true)
{
BigInteger bigInteger2 = kCalculator.NextK();
ECPoint eCPoint = eCMultiplier.Multiply(parameters.G, bigInteger2).Normalize();
bigInteger3 = eCPoint.AffineXCoord.ToBigInteger().Mod(n);
if (bigInteger3.SignValue != 0)
{
bigInteger4 = bigInteger2.ModInverse(n).Multiply(bigInteger.Add(d.Multiply(bigInteger3))).Mod(n);
if (bigInteger4.SignValue != 0)
{
break;
}
}
}
return new BigInteger[2] { bigInteger3, bigInteger4 };
}
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
BigInteger n = key.Parameters.N;
if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger bigInteger = CalculateE(n, message);
BigInteger val = s.ModInverse(n);
BigInteger a = bigInteger.Multiply(val).Mod(n);
BigInteger b = r.Multiply(val).Mod(n);
ECPoint g = key.Parameters.G;
ECPoint q = ((ECPublicKeyParameters)key).Q;
ECPoint eCPoint = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b);
if (eCPoint.IsInfinity)
{
return false;
}
ECCurve curve = eCPoint.Curve;
if (curve != null)
{
BigInteger cofactor = curve.Cofactor;
if (cofactor != null && cofactor.CompareTo(Eight) <= 0)
{
ECFieldElement denominator = GetDenominator(curve.CoordinateSystem, eCPoint);
if (denominator != null && !denominator.IsZero)
{
ECFieldElement xCoord = eCPoint.XCoord;
while (curve.IsValidFieldElement(r))
{
ECFieldElement eCFieldElement = curve.FromBigInteger(r).Multiply(denominator);
if (eCFieldElement.Equals(xCoord))
{
return true;
}
r = r.Add(n);
}
return false;
}
}
}
BigInteger bigInteger2 = eCPoint.Normalize().AffineXCoord.ToBigInteger().Mod(n);
return bigInteger2.Equals(r);
}
protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
{
int num = message.Length * 8;
BigInteger bigInteger = new BigInteger(1, message);
if (n.BitLength < num)
{
bigInteger = bigInteger.ShiftRight(num - n.BitLength);
}
return bigInteger;
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
protected virtual ECFieldElement GetDenominator(int coordinateSystem, ECPoint p)
{
switch (coordinateSystem)
{
case 1:
case 6:
case 7:
return p.GetZCoord(0);
case 2:
case 3:
case 4:
return p.GetZCoord(0).Square();
default:
return null;
}
}
protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
{
if (needed)
{
if (provided == null)
{
return new SecureRandom();
}
return provided;
}
return null;
}
}

View File

@@ -0,0 +1,131 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class ECGost3410Signer : IDsaExt, IDsa
{
private ECKeyParameters key;
private SecureRandom random;
private bool forSigning;
public virtual string AlgorithmName => key.AlgorithmName;
public virtual BigInteger Order => key.Parameters.N;
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
random = parametersWithRandom.Random;
parameters = parametersWithRandom.Parameters;
}
else
{
random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
{
throw new InvalidKeyException("EC private key required for signing");
}
key = (ECPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
{
throw new InvalidKeyException("EC public key required for verification");
}
key = (ECPublicKeyParameters)parameters;
}
}
public virtual BigInteger[] GenerateSignature(byte[] message)
{
if (!forSigning)
{
throw new InvalidOperationException("not initialized for signing");
}
byte[] array = new byte[message.Length];
for (int i = 0; i != array.Length; i++)
{
array[i] = message[array.Length - 1 - i];
}
BigInteger val = new BigInteger(1, array);
ECDomainParameters parameters = key.Parameters;
BigInteger n = parameters.N;
BigInteger d = ((ECPrivateKeyParameters)key).D;
BigInteger bigInteger = null;
ECMultiplier eCMultiplier = CreateBasePointMultiplier();
BigInteger bigInteger3;
while (true)
{
BigInteger bigInteger2 = new BigInteger(n.BitLength, random);
if (bigInteger2.SignValue == 0)
{
continue;
}
ECPoint eCPoint = eCMultiplier.Multiply(parameters.G, bigInteger2).Normalize();
bigInteger3 = eCPoint.AffineXCoord.ToBigInteger().Mod(n);
if (bigInteger3.SignValue != 0)
{
bigInteger = bigInteger2.Multiply(val).Add(d.Multiply(bigInteger3)).Mod(n);
if (bigInteger.SignValue != 0)
{
break;
}
}
}
return new BigInteger[2] { bigInteger3, bigInteger };
}
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
if (forSigning)
{
throw new InvalidOperationException("not initialized for verification");
}
byte[] array = new byte[message.Length];
for (int i = 0; i != array.Length; i++)
{
array[i] = message[array.Length - 1 - i];
}
BigInteger bigInteger = new BigInteger(1, array);
BigInteger n = key.Parameters.N;
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
{
return false;
}
if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
{
return false;
}
BigInteger val = bigInteger.ModInverse(n);
BigInteger a = s.Multiply(val).Mod(n);
BigInteger b = n.Subtract(r).Multiply(val).Mod(n);
ECPoint g = key.Parameters.G;
ECPoint q = ((ECPublicKeyParameters)key).Q;
ECPoint eCPoint = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b).Normalize();
if (eCPoint.IsInfinity)
{
return false;
}
BigInteger bigInteger2 = eCPoint.AffineXCoord.ToBigInteger().Mod(n);
return bigInteger2.Equals(r);
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
}

View File

@@ -0,0 +1,121 @@
using System;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class ECNRSigner : IDsaExt, IDsa
{
private bool forSigning;
private ECKeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName => "ECNR";
public virtual BigInteger Order => key.Parameters.N;
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
random = parametersWithRandom.Random;
parameters = parametersWithRandom.Parameters;
}
else
{
random = new SecureRandom();
}
if (!(parameters is ECPrivateKeyParameters))
{
throw new InvalidKeyException("EC private key required for signing");
}
key = (ECPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is ECPublicKeyParameters))
{
throw new InvalidKeyException("EC public key required for verification");
}
key = (ECPublicKeyParameters)parameters;
}
}
public virtual BigInteger[] GenerateSignature(byte[] message)
{
if (!forSigning)
{
throw new InvalidOperationException("not initialised for signing");
}
BigInteger order = Order;
int bitLength = order.BitLength;
BigInteger bigInteger = new BigInteger(1, message);
int bitLength2 = bigInteger.BitLength;
ECPrivateKeyParameters eCPrivateKeyParameters = (ECPrivateKeyParameters)key;
if (bitLength2 > bitLength)
{
throw new DataLengthException("input too large for ECNR key.");
}
BigInteger bigInteger2 = null;
BigInteger bigInteger3 = null;
AsymmetricCipherKeyPair asymmetricCipherKeyPair;
do
{
ECKeyPairGenerator eCKeyPairGenerator = new ECKeyPairGenerator();
eCKeyPairGenerator.Init(new ECKeyGenerationParameters(eCPrivateKeyParameters.Parameters, random));
asymmetricCipherKeyPair = eCKeyPairGenerator.GenerateKeyPair();
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)asymmetricCipherKeyPair.Public;
BigInteger bigInteger4 = eCPublicKeyParameters.Q.AffineXCoord.ToBigInteger();
bigInteger2 = bigInteger4.Add(bigInteger).Mod(order);
}
while (bigInteger2.SignValue == 0);
BigInteger d = eCPrivateKeyParameters.D;
BigInteger d2 = ((ECPrivateKeyParameters)asymmetricCipherKeyPair.Private).D;
bigInteger3 = d2.Subtract(bigInteger2.Multiply(d)).Mod(order);
return new BigInteger[2] { bigInteger2, bigInteger3 };
}
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
if (forSigning)
{
throw new InvalidOperationException("not initialised for verifying");
}
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)key;
BigInteger n = eCPublicKeyParameters.Parameters.N;
int bitLength = n.BitLength;
BigInteger bigInteger = new BigInteger(1, message);
int bitLength2 = bigInteger.BitLength;
if (bitLength2 > bitLength)
{
throw new DataLengthException("input too large for ECNR key.");
}
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
{
return false;
}
if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
{
return false;
}
ECPoint g = eCPublicKeyParameters.Parameters.G;
ECPoint q = eCPublicKeyParameters.Q;
ECPoint eCPoint = ECAlgorithms.SumOfTwoMultiplies(g, s, q, r).Normalize();
if (eCPoint.IsInfinity)
{
return false;
}
BigInteger n2 = eCPoint.AffineXCoord.ToBigInteger();
BigInteger bigInteger2 = r.Subtract(n2).Mod(n);
return bigInteger2.Equals(bigInteger);
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC.Rfc8032;
namespace Org.BouncyCastle.Crypto.Signers;
public class Ed25519Signer : ISigner
{
private class Buffer : MemoryStream
{
internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, Ed25519PublicKeyParameters publicKey)
{
lock (this)
{
byte[] buffer = GetBuffer();
int msgLen = (int)Position;
byte[] array = new byte[Ed25519PrivateKeyParameters.SignatureSize];
privateKey.Sign(Ed25519.Algorithm.Ed25519, publicKey, null, buffer, 0, msgLen, array, 0);
Reset();
return array;
}
}
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] signature)
{
lock (this)
{
byte[] buffer = GetBuffer();
int mLen = (int)Position;
byte[] encoded = publicKey.GetEncoded();
bool result = Ed25519.Verify(signature, 0, encoded, 0, buffer, 0, mLen);
Reset();
return result;
}
}
internal void Reset()
{
lock (this)
{
long position = Position;
Array.Clear(GetBuffer(), 0, (int)position);
Position = 0L;
}
}
}
private readonly Buffer buffer = new Buffer();
private bool forSigning;
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;
public virtual string AlgorithmName => "Ed25519";
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
privateKey = (Ed25519PrivateKeyParameters)parameters;
publicKey = privateKey.GeneratePublicKey();
}
else
{
privateKey = null;
publicKey = (Ed25519PublicKeyParameters)parameters;
}
Reset();
}
public virtual void Update(byte b)
{
buffer.WriteByte(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
buffer.Write(buf, off, len);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning || privateKey == null)
{
throw new InvalidOperationException("Ed25519Signer not initialised for signature generation.");
}
return buffer.GenerateSignature(privateKey, publicKey);
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || publicKey == null)
{
throw new InvalidOperationException("Ed25519Signer not initialised for verification");
}
return buffer.VerifySignature(publicKey, signature);
}
public virtual void Reset()
{
buffer.Reset();
}
}

View File

@@ -0,0 +1,115 @@
using System;
using System.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Ed25519ctxSigner : ISigner
{
private class Buffer : MemoryStream
{
internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, Ed25519PublicKeyParameters publicKey, byte[] ctx)
{
lock (this)
{
byte[] buffer = GetBuffer();
int msgLen = (int)Position;
byte[] array = new byte[Ed25519PrivateKeyParameters.SignatureSize];
privateKey.Sign(Ed25519.Algorithm.Ed25519ctx, publicKey, ctx, buffer, 0, msgLen, array, 0);
Reset();
return array;
}
}
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
{
lock (this)
{
byte[] buffer = GetBuffer();
int mLen = (int)Position;
byte[] encoded = publicKey.GetEncoded();
bool result = Ed25519.Verify(signature, 0, encoded, 0, ctx, buffer, 0, mLen);
Reset();
return result;
}
}
internal void Reset()
{
lock (this)
{
long position = Position;
Array.Clear(GetBuffer(), 0, (int)position);
Position = 0L;
}
}
}
private readonly Buffer buffer = new Buffer();
private readonly byte[] context;
private bool forSigning;
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;
public virtual string AlgorithmName => "Ed25519ctx";
public Ed25519ctxSigner(byte[] context)
{
this.context = Arrays.Clone(context);
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
privateKey = (Ed25519PrivateKeyParameters)parameters;
publicKey = privateKey.GeneratePublicKey();
}
else
{
privateKey = null;
publicKey = (Ed25519PublicKeyParameters)parameters;
}
Reset();
}
public virtual void Update(byte b)
{
buffer.WriteByte(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
buffer.Write(buf, off, len);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning || privateKey == null)
{
throw new InvalidOperationException("Ed25519ctxSigner not initialised for signature generation.");
}
return buffer.GenerateSignature(privateKey, publicKey, context);
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || publicKey == null)
{
throw new InvalidOperationException("Ed25519ctxSigner not initialised for verification");
}
return buffer.VerifySignature(publicKey, context, signature);
}
public virtual void Reset()
{
buffer.Reset();
}
}

View File

@@ -0,0 +1,83 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Ed25519phSigner : ISigner
{
private readonly IDigest prehash = Ed25519.CreatePrehash();
private readonly byte[] context;
private bool forSigning;
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;
public virtual string AlgorithmName => "Ed25519ph";
public Ed25519phSigner(byte[] context)
{
this.context = Arrays.Clone(context);
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
privateKey = (Ed25519PrivateKeyParameters)parameters;
publicKey = privateKey.GeneratePublicKey();
}
else
{
privateKey = null;
publicKey = (Ed25519PublicKeyParameters)parameters;
}
Reset();
}
public virtual void Update(byte b)
{
prehash.Update(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
prehash.BlockUpdate(buf, off, len);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning || privateKey == null)
{
throw new InvalidOperationException("Ed25519phSigner not initialised for signature generation.");
}
byte[] array = new byte[Ed25519.PrehashSize];
if (Ed25519.PrehashSize != prehash.DoFinal(array, 0))
{
throw new InvalidOperationException("Prehash digest failed");
}
byte[] array2 = new byte[Ed25519PrivateKeyParameters.SignatureSize];
privateKey.Sign(Ed25519.Algorithm.Ed25519ph, publicKey, context, array, 0, Ed25519.PrehashSize, array2, 0);
return array2;
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || publicKey == null)
{
throw new InvalidOperationException("Ed25519phSigner not initialised for verification");
}
byte[] encoded = publicKey.GetEncoded();
return Ed25519.VerifyPrehash(signature, 0, encoded, 0, context, prehash);
}
public void Reset()
{
prehash.Reset();
}
}

View File

@@ -0,0 +1,115 @@
using System;
using System.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Ed448Signer : ISigner
{
private class Buffer : MemoryStream
{
internal byte[] GenerateSignature(Ed448PrivateKeyParameters privateKey, Ed448PublicKeyParameters publicKey, byte[] ctx)
{
lock (this)
{
byte[] buffer = GetBuffer();
int msgLen = (int)Position;
byte[] array = new byte[Ed448PrivateKeyParameters.SignatureSize];
privateKey.Sign(Ed448.Algorithm.Ed448, publicKey, ctx, buffer, 0, msgLen, array, 0);
Reset();
return array;
}
}
internal bool VerifySignature(Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
{
lock (this)
{
byte[] buffer = GetBuffer();
int mLen = (int)Position;
byte[] encoded = publicKey.GetEncoded();
bool result = Ed448.Verify(signature, 0, encoded, 0, ctx, buffer, 0, mLen);
Reset();
return result;
}
}
internal void Reset()
{
lock (this)
{
long position = Position;
Array.Clear(GetBuffer(), 0, (int)position);
Position = 0L;
}
}
}
private readonly Buffer buffer = new Buffer();
private readonly byte[] context;
private bool forSigning;
private Ed448PrivateKeyParameters privateKey;
private Ed448PublicKeyParameters publicKey;
public virtual string AlgorithmName => "Ed448";
public Ed448Signer(byte[] context)
{
this.context = Arrays.Clone(context);
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
privateKey = (Ed448PrivateKeyParameters)parameters;
publicKey = privateKey.GeneratePublicKey();
}
else
{
privateKey = null;
publicKey = (Ed448PublicKeyParameters)parameters;
}
Reset();
}
public virtual void Update(byte b)
{
buffer.WriteByte(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
buffer.Write(buf, off, len);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning || privateKey == null)
{
throw new InvalidOperationException("Ed448Signer not initialised for signature generation.");
}
return buffer.GenerateSignature(privateKey, publicKey, context);
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || publicKey == null)
{
throw new InvalidOperationException("Ed448Signer not initialised for verification");
}
return buffer.VerifySignature(publicKey, context, signature);
}
public virtual void Reset()
{
buffer.Reset();
}
}

View File

@@ -0,0 +1,83 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Ed448phSigner : ISigner
{
private readonly IXof prehash = Ed448.CreatePrehash();
private readonly byte[] context;
private bool forSigning;
private Ed448PrivateKeyParameters privateKey;
private Ed448PublicKeyParameters publicKey;
public virtual string AlgorithmName => "Ed448ph";
public Ed448phSigner(byte[] context)
{
this.context = Arrays.Clone(context);
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
if (forSigning)
{
privateKey = (Ed448PrivateKeyParameters)parameters;
publicKey = privateKey.GeneratePublicKey();
}
else
{
privateKey = null;
publicKey = (Ed448PublicKeyParameters)parameters;
}
Reset();
}
public virtual void Update(byte b)
{
prehash.Update(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
prehash.BlockUpdate(buf, off, len);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning || privateKey == null)
{
throw new InvalidOperationException("Ed448phSigner not initialised for signature generation.");
}
byte[] array = new byte[Ed448.PrehashSize];
if (Ed448.PrehashSize != prehash.DoFinal(array, 0, Ed448.PrehashSize))
{
throw new InvalidOperationException("Prehash digest failed");
}
byte[] array2 = new byte[Ed448PrivateKeyParameters.SignatureSize];
privateKey.Sign(Ed448.Algorithm.Ed448ph, publicKey, context, array, 0, Ed448.PrehashSize, array2, 0);
return array2;
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || publicKey == null)
{
throw new InvalidOperationException("Ed448phSigner not initialised for verification");
}
byte[] encoded = publicKey.GetEncoded();
return Ed448.VerifyPrehash(signature, 0, encoded, 0, context, prehash);
}
public void Reset()
{
prehash.Reset();
}
}

View File

@@ -0,0 +1,90 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class GenericSigner : ISigner
{
private readonly IAsymmetricBlockCipher engine;
private readonly IDigest digest;
private bool forSigning;
public virtual string AlgorithmName => "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")";
public GenericSigner(IAsymmetricBlockCipher engine, IDigest digest)
{
this.engine = engine;
this.digest = digest;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter asymmetricKeyParameter = ((!(parameters is ParametersWithRandom)) ? ((AsymmetricKeyParameter)parameters) : ((AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters));
if (forSigning && !asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Signing requires private key.");
}
if (!forSigning && asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Verification requires public key.");
}
Reset();
engine.Init(forSigning, parameters);
}
public virtual void Update(byte input)
{
digest.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning)
{
throw new InvalidOperationException("GenericSigner not initialised for signature generation.");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
return engine.ProcessBlock(array, 0, array.Length);
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
{
throw new InvalidOperationException("GenericSigner not initialised for verification");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
try
{
byte[] array2 = engine.ProcessBlock(signature, 0, signature.Length);
if (array2.Length < array.Length)
{
byte[] array3 = new byte[array.Length];
Array.Copy(array2, 0, array3, array3.Length - array2.Length, array2.Length);
array2 = array3;
}
return Arrays.ConstantTimeAreEqual(array2, array);
}
catch (Exception)
{
return false;
}
}
public virtual void Reset()
{
digest.Reset();
}
}

View File

@@ -0,0 +1,106 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class Gost3410DigestSigner : ISigner
{
private readonly IDigest digest;
private readonly IDsa dsaSigner;
private readonly int size;
private int halfSize;
private bool forSigning;
public virtual string AlgorithmName => digest.AlgorithmName + "with" + dsaSigner.AlgorithmName;
public Gost3410DigestSigner(IDsa signer, IDigest digest)
{
dsaSigner = signer;
this.digest = digest;
halfSize = digest.GetDigestSize();
size = halfSize * 2;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter asymmetricKeyParameter = ((!(parameters is ParametersWithRandom)) ? ((AsymmetricKeyParameter)parameters) : ((AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters));
if (forSigning && !asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Signing Requires Private Key.");
}
if (!forSigning && asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Verification Requires Public Key.");
}
Reset();
dsaSigner.Init(forSigning, parameters);
}
public virtual void Update(byte input)
{
digest.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning)
{
throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation.");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
try
{
BigInteger[] array2 = dsaSigner.GenerateSignature(array);
byte[] array3 = new byte[size];
byte[] array4 = array2[0].ToByteArrayUnsigned();
byte[] array5 = array2[1].ToByteArrayUnsigned();
array5.CopyTo(array3, halfSize - array5.Length);
array4.CopyTo(array3, size - array4.Length);
return array3;
}
catch (Exception ex)
{
throw new SignatureException(ex.Message, ex);
}
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
{
throw new InvalidOperationException("DSADigestSigner not initialised for verification");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
BigInteger r;
BigInteger s;
try
{
r = new BigInteger(1, signature, halfSize, halfSize);
s = new BigInteger(1, signature, 0, halfSize);
}
catch (Exception exception)
{
throw new SignatureException("error decoding signature bytes.", exception);
}
return dsaSigner.VerifySignature(array, r, s);
}
public virtual void Reset()
{
digest.Reset();
}
}

View File

@@ -0,0 +1,92 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class Gost3410Signer : IDsaExt, IDsa
{
private Gost3410KeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName => "GOST3410";
public virtual BigInteger Order => key.Parameters.Q;
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
random = parametersWithRandom.Random;
parameters = parametersWithRandom.Parameters;
}
else
{
random = new SecureRandom();
}
if (!(parameters is Gost3410PrivateKeyParameters))
{
throw new InvalidKeyException("GOST3410 private key required for signing");
}
key = (Gost3410PrivateKeyParameters)parameters;
}
else
{
if (!(parameters is Gost3410PublicKeyParameters))
{
throw new InvalidKeyException("GOST3410 public key required for signing");
}
key = (Gost3410PublicKeyParameters)parameters;
}
}
public virtual BigInteger[] GenerateSignature(byte[] message)
{
byte[] array = new byte[message.Length];
for (int i = 0; i != array.Length; i++)
{
array[i] = message[array.Length - 1 - i];
}
BigInteger val = new BigInteger(1, array);
Gost3410Parameters parameters = key.Parameters;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(parameters.Q.BitLength, random);
}
while (bigInteger.CompareTo(parameters.Q) >= 0);
BigInteger bigInteger2 = parameters.A.ModPow(bigInteger, parameters.P).Mod(parameters.Q);
BigInteger bigInteger3 = bigInteger.Multiply(val).Add(((Gost3410PrivateKeyParameters)key).X.Multiply(bigInteger2)).Mod(parameters.Q);
return new BigInteger[2] { bigInteger2, bigInteger3 };
}
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
byte[] array = new byte[message.Length];
for (int i = 0; i != array.Length; i++)
{
array[i] = message[array.Length - 1 - i];
}
BigInteger bigInteger = new BigInteger(1, array);
Gost3410Parameters parameters = key.Parameters;
if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0)
{
return false;
}
if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0)
{
return false;
}
BigInteger val = bigInteger.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q);
BigInteger e = s.Multiply(val).Mod(parameters.Q);
BigInteger e2 = parameters.Q.Subtract(r).Multiply(val).Mod(parameters.Q);
e = parameters.A.ModPow(e, parameters.P);
e2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(e2, parameters.P);
BigInteger bigInteger2 = e.Multiply(e2).Mod(parameters.P).Mod(parameters.Q);
return bigInteger2.Equals(r);
}
}

View File

@@ -0,0 +1,108 @@
using System;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class HMacDsaKCalculator : IDsaKCalculator
{
private readonly HMac hMac;
private readonly byte[] K;
private readonly byte[] V;
private BigInteger n;
public virtual bool IsDeterministic => true;
public HMacDsaKCalculator(IDigest digest)
{
hMac = new HMac(digest);
V = new byte[hMac.GetMacSize()];
K = new byte[hMac.GetMacSize()];
}
public virtual void Init(BigInteger n, SecureRandom random)
{
throw new InvalidOperationException("Operation not supported");
}
public void Init(BigInteger n, BigInteger d, byte[] message)
{
this.n = n;
Arrays.Fill(V, 1);
Arrays.Fill(K, 0);
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(n);
byte[] array = new byte[unsignedByteLength];
byte[] array2 = BigIntegers.AsUnsignedByteArray(d);
Array.Copy(array2, 0, array, array.Length - array2.Length, array2.Length);
byte[] array3 = new byte[unsignedByteLength];
BigInteger bigInteger = BitsToInt(message);
if (bigInteger.CompareTo(n) >= 0)
{
bigInteger = bigInteger.Subtract(n);
}
byte[] array4 = BigIntegers.AsUnsignedByteArray(bigInteger);
Array.Copy(array4, 0, array3, array3.Length - array4.Length, array4.Length);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(0);
hMac.BlockUpdate(array, 0, array.Length);
hMac.BlockUpdate(array3, 0, array3.Length);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(1);
hMac.BlockUpdate(array, 0, array.Length);
hMac.BlockUpdate(array3, 0, array3.Length);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
public virtual BigInteger NextK()
{
byte[] array = new byte[BigIntegers.GetUnsignedByteLength(n)];
BigInteger bigInteger;
while (true)
{
int num;
for (int i = 0; i < array.Length; i += num)
{
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
num = System.Math.Min(array.Length - i, V.Length);
Array.Copy(V, 0, array, i, num);
}
bigInteger = BitsToInt(array);
if (bigInteger.SignValue > 0 && bigInteger.CompareTo(n) < 0)
{
break;
}
hMac.BlockUpdate(V, 0, V.Length);
hMac.Update(0);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
hMac.DoFinal(V, 0);
}
return bigInteger;
}
private BigInteger BitsToInt(byte[] t)
{
BigInteger bigInteger = new BigInteger(1, t);
if (t.Length * 8 > n.BitLength)
{
bigInteger = bigInteger.ShiftRight(t.Length * 8 - n.BitLength);
}
return bigInteger;
}
}

View File

@@ -0,0 +1,10 @@
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Signers;
public interface IDsaEncoding
{
BigInteger[] Decode(BigInteger n, byte[] encoding);
byte[] Encode(BigInteger n, BigInteger r, BigInteger s);
}

View File

@@ -0,0 +1,15 @@
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public interface IDsaKCalculator
{
bool IsDeterministic { get; }
void Init(BigInteger n, SecureRandom random);
void Init(BigInteger n, BigInteger d, byte[] message);
BigInteger NextK();
}

View File

@@ -0,0 +1,459 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Iso9796d2PssSigner : ISignerWithRecovery, ISigner
{
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerImplicit = 188;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD160 = 12748;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD128 = 13004;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha1 = 13260;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha256 = 13516;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha512 = 13772;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha384 = 14028;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerWhirlpool = 14284;
private IDigest digest;
private IAsymmetricBlockCipher cipher;
private SecureRandom random;
private byte[] standardSalt;
private int hLen;
private int trailer;
private int keyBits;
private byte[] block;
private byte[] mBuf;
private int messageLength;
private readonly int saltLength;
private bool fullMessage;
private byte[] recoveredMessage;
private byte[] preSig;
private byte[] preBlock;
private int preMStart;
private int preTLength;
public virtual string AlgorithmName => digest.AlgorithmName + "withISO9796-2S2";
public byte[] GetRecoveredMessage()
{
return recoveredMessage;
}
public Iso9796d2PssSigner(IAsymmetricBlockCipher cipher, IDigest digest, int saltLength, bool isImplicit)
{
this.cipher = cipher;
this.digest = digest;
hLen = digest.GetDigestSize();
this.saltLength = saltLength;
if (isImplicit)
{
trailer = 188;
return;
}
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("no valid trailer", "digest");
}
trailer = IsoTrailers.GetTrailer(digest);
}
public Iso9796d2PssSigner(IAsymmetricBlockCipher cipher, IDigest digest, int saltLength)
: this(cipher, digest, saltLength, isImplicit: false)
{
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
RsaKeyParameters rsaKeyParameters;
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
rsaKeyParameters = (RsaKeyParameters)parametersWithRandom.Parameters;
if (forSigning)
{
random = parametersWithRandom.Random;
}
}
else if (parameters is ParametersWithSalt)
{
if (!forSigning)
{
throw new ArgumentException("ParametersWithSalt only valid for signing", "parameters");
}
ParametersWithSalt parametersWithSalt = (ParametersWithSalt)parameters;
rsaKeyParameters = (RsaKeyParameters)parametersWithSalt.Parameters;
standardSalt = parametersWithSalt.GetSalt();
if (standardSalt.Length != saltLength)
{
throw new ArgumentException("Fixed salt is of wrong length");
}
}
else
{
rsaKeyParameters = (RsaKeyParameters)parameters;
if (forSigning)
{
random = new SecureRandom();
}
}
cipher.Init(forSigning, rsaKeyParameters);
keyBits = rsaKeyParameters.Modulus.BitLength;
block = new byte[(keyBits + 7) / 8];
if (trailer == 188)
{
mBuf = new byte[block.Length - digest.GetDigestSize() - saltLength - 1 - 1];
}
else
{
mBuf = new byte[block.Length - digest.GetDigestSize() - saltLength - 1 - 2];
}
Reset();
}
private bool IsSameAs(byte[] a, byte[] b)
{
if (messageLength != b.Length)
{
return false;
}
bool result = true;
for (int i = 0; i != b.Length; i++)
{
if (a[i] != b[i])
{
result = false;
}
}
return result;
}
private void ClearBlock(byte[] block)
{
Array.Clear(block, 0, block.Length);
}
public virtual void UpdateWithRecoveredMessage(byte[] signature)
{
byte[] array = cipher.ProcessBlock(signature, 0, signature.Length);
if (array.Length < (keyBits + 7) / 8)
{
byte[] array2 = new byte[(keyBits + 7) / 8];
Array.Copy(array, 0, array2, array2.Length - array.Length, array.Length);
ClearBlock(array);
array = array2;
}
int num;
if (((array[^1] & 0xFF) ^ 0xBC) == 0)
{
num = 1;
}
else
{
int num2 = ((array[^2] & 0xFF) << 8) | (array[^1] & 0xFF);
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("unrecognised hash in signature");
}
if (num2 != IsoTrailers.GetTrailer(digest))
{
throw new InvalidOperationException("signer initialised with wrong digest for trailer " + num2);
}
num = 2;
}
byte[] output = new byte[hLen];
digest.DoFinal(output, 0);
byte[] array3 = MaskGeneratorFunction1(array, array.Length - hLen - num, hLen, array.Length - hLen - num);
byte[] array5;
for (int i = 0; i != array3.Length; i++)
{
byte[] array4 = (array5 = array);
int num3 = i;
nint num4 = num3;
array4[num3] = (byte)(array5[num4] ^ array3[i]);
}
(array5 = array)[0] = (byte)(array5[0] & 0x7F);
int num5 = 0;
while (num5 < array.Length && array[num5++] != 1)
{
}
if (num5 >= array.Length)
{
ClearBlock(array);
}
fullMessage = num5 > 1;
recoveredMessage = new byte[array3.Length - num5 - saltLength];
Array.Copy(array, num5, recoveredMessage, 0, recoveredMessage.Length);
recoveredMessage.CopyTo(mBuf, 0);
preSig = signature;
preBlock = array;
preMStart = num5;
preTLength = num;
}
public virtual void Update(byte input)
{
if (preSig == null && messageLength < mBuf.Length)
{
mBuf[messageLength++] = input;
}
else
{
digest.Update(input);
}
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
if (preSig == null)
{
while (length > 0 && messageLength < mBuf.Length)
{
Update(input[inOff]);
inOff++;
length--;
}
}
if (length > 0)
{
digest.BlockUpdate(input, inOff, length);
}
}
public virtual void Reset()
{
digest.Reset();
messageLength = 0;
if (mBuf != null)
{
ClearBlock(mBuf);
}
if (recoveredMessage != null)
{
ClearBlock(recoveredMessage);
recoveredMessage = null;
}
fullMessage = false;
if (preSig != null)
{
preSig = null;
ClearBlock(preBlock);
preBlock = null;
}
}
public virtual byte[] GenerateSignature()
{
int digestSize = digest.GetDigestSize();
byte[] array = new byte[digestSize];
digest.DoFinal(array, 0);
byte[] array2 = new byte[8];
LtoOSP(messageLength * 8, array2);
digest.BlockUpdate(array2, 0, array2.Length);
digest.BlockUpdate(mBuf, 0, messageLength);
digest.BlockUpdate(array, 0, array.Length);
byte[] array3;
if (standardSalt != null)
{
array3 = standardSalt;
}
else
{
array3 = new byte[saltLength];
random.NextBytes(array3);
}
digest.BlockUpdate(array3, 0, array3.Length);
byte[] array4 = new byte[digest.GetDigestSize()];
digest.DoFinal(array4, 0);
int num = 2;
if (trailer == 188)
{
num = 1;
}
int num2 = block.Length - messageLength - array3.Length - hLen - num - 1;
block[num2] = 1;
Array.Copy(mBuf, 0, block, num2 + 1, messageLength);
Array.Copy(array3, 0, block, num2 + 1 + messageLength, array3.Length);
byte[] array5 = MaskGeneratorFunction1(array4, 0, array4.Length, block.Length - hLen - num);
byte[] array7;
for (int i = 0; i != array5.Length; i++)
{
byte[] array6 = (array7 = block);
int num3 = i;
nint num4 = num3;
array6[num3] = (byte)(array7[num4] ^ array5[i]);
}
Array.Copy(array4, 0, block, block.Length - hLen - num, hLen);
if (trailer == 188)
{
block[block.Length - 1] = 188;
}
else
{
block[block.Length - 2] = (byte)((uint)trailer >> 8);
block[block.Length - 1] = (byte)trailer;
}
(array7 = block)[0] = (byte)(array7[0] & 0x7F);
byte[] result = cipher.ProcessBlock(block, 0, block.Length);
ClearBlock(mBuf);
ClearBlock(block);
messageLength = 0;
return result;
}
public virtual bool VerifySignature(byte[] signature)
{
byte[] array = new byte[hLen];
digest.DoFinal(array, 0);
int num = 0;
if (preSig == null)
{
try
{
UpdateWithRecoveredMessage(signature);
}
catch (Exception)
{
return false;
}
}
else if (!Arrays.AreEqual(preSig, signature))
{
throw new InvalidOperationException("UpdateWithRecoveredMessage called on different signature");
}
byte[] array2 = preBlock;
num = preMStart;
int num2 = preTLength;
preSig = null;
preBlock = null;
byte[] array3 = new byte[8];
LtoOSP(recoveredMessage.Length * 8, array3);
digest.BlockUpdate(array3, 0, array3.Length);
if (recoveredMessage.Length != 0)
{
digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length);
}
digest.BlockUpdate(array, 0, array.Length);
if (standardSalt != null)
{
digest.BlockUpdate(standardSalt, 0, standardSalt.Length);
}
else
{
digest.BlockUpdate(array2, num + recoveredMessage.Length, saltLength);
}
byte[] array4 = new byte[digest.GetDigestSize()];
digest.DoFinal(array4, 0);
int num3 = array2.Length - num2 - array4.Length;
bool flag = true;
for (int i = 0; i != array4.Length; i++)
{
if (array4[i] != array2[num3 + i])
{
flag = false;
}
}
ClearBlock(array2);
ClearBlock(array4);
if (!flag)
{
fullMessage = false;
messageLength = 0;
ClearBlock(recoveredMessage);
return false;
}
if (messageLength != 0 && !IsSameAs(mBuf, recoveredMessage))
{
messageLength = 0;
ClearBlock(mBuf);
return false;
}
messageLength = 0;
ClearBlock(mBuf);
return true;
}
public virtual bool HasFullMessage()
{
return fullMessage;
}
private void ItoOSP(int i, byte[] sp)
{
sp[0] = (byte)((uint)i >> 24);
sp[1] = (byte)((uint)i >> 16);
sp[2] = (byte)((uint)i >> 8);
sp[3] = (byte)i;
}
private void LtoOSP(long l, byte[] sp)
{
sp[0] = (byte)((ulong)l >> 56);
sp[1] = (byte)((ulong)l >> 48);
sp[2] = (byte)((ulong)l >> 40);
sp[3] = (byte)((ulong)l >> 32);
sp[4] = (byte)((ulong)l >> 24);
sp[5] = (byte)((ulong)l >> 16);
sp[6] = (byte)((ulong)l >> 8);
sp[7] = (byte)l;
}
private byte[] MaskGeneratorFunction1(byte[] Z, int zOff, int zLen, int length)
{
byte[] array = new byte[length];
byte[] array2 = new byte[hLen];
byte[] array3 = new byte[4];
int num = 0;
digest.Reset();
do
{
ItoOSP(num, array3);
digest.BlockUpdate(Z, zOff, zLen);
digest.BlockUpdate(array3, 0, array3.Length);
digest.DoFinal(array2, 0);
Array.Copy(array2, 0, array, num * hLen, hLen);
}
while (++num < length / hLen);
if (num * hLen < length)
{
ItoOSP(num, array3);
digest.BlockUpdate(Z, zOff, zLen);
digest.BlockUpdate(array3, 0, array3.Length);
digest.DoFinal(array2, 0);
Array.Copy(array2, 0, array, num * hLen, array.Length - num * hLen);
}
return array;
}
}

View File

@@ -0,0 +1,433 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class Iso9796d2Signer : ISignerWithRecovery, ISigner
{
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerImplicit = 188;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD160 = 12748;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerRipeMD128 = 13004;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha1 = 13260;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha256 = 13516;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha512 = 13772;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerSha384 = 14028;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TrailerWhirlpool = 14284;
private IDigest digest;
private IAsymmetricBlockCipher cipher;
private int trailer;
private int keyBits;
private byte[] block;
private byte[] mBuf;
private int messageLength;
private bool fullMessage;
private byte[] recoveredMessage;
private byte[] preSig;
private byte[] preBlock;
public virtual string AlgorithmName => digest.AlgorithmName + "withISO9796-2S1";
public byte[] GetRecoveredMessage()
{
return recoveredMessage;
}
public Iso9796d2Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
{
this.cipher = cipher;
this.digest = digest;
if (isImplicit)
{
trailer = 188;
return;
}
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("no valid trailer", "digest");
}
trailer = IsoTrailers.GetTrailer(digest);
}
public Iso9796d2Signer(IAsymmetricBlockCipher cipher, IDigest digest)
: this(cipher, digest, isImplicit: false)
{
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)parameters;
cipher.Init(forSigning, rsaKeyParameters);
keyBits = rsaKeyParameters.Modulus.BitLength;
block = new byte[(keyBits + 7) / 8];
if (trailer == 188)
{
mBuf = new byte[block.Length - digest.GetDigestSize() - 2];
}
else
{
mBuf = new byte[block.Length - digest.GetDigestSize() - 3];
}
Reset();
}
private bool IsSameAs(byte[] a, byte[] b)
{
int num;
if (messageLength > mBuf.Length)
{
if (mBuf.Length > b.Length)
{
return false;
}
num = mBuf.Length;
}
else
{
if (messageLength != b.Length)
{
return false;
}
num = b.Length;
}
bool result = true;
for (int i = 0; i != num; i++)
{
if (a[i] != b[i])
{
result = false;
}
}
return result;
}
private void ClearBlock(byte[] block)
{
Array.Clear(block, 0, block.Length);
}
public virtual void UpdateWithRecoveredMessage(byte[] signature)
{
byte[] array = cipher.ProcessBlock(signature, 0, signature.Length);
if (((array[0] & 0xC0) ^ 0x40) != 0)
{
throw new InvalidCipherTextException("malformed signature");
}
if (((array[^1] & 0xF) ^ 0xC) != 0)
{
throw new InvalidCipherTextException("malformed signature");
}
int num = 0;
if (((array[^1] & 0xFF) ^ 0xBC) == 0)
{
num = 1;
}
else
{
int num2 = ((array[^2] & 0xFF) << 8) | (array[^1] & 0xFF);
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("unrecognised hash in signature");
}
if (num2 != IsoTrailers.GetTrailer(digest))
{
throw new InvalidOperationException("signer initialised with wrong digest for trailer " + num2);
}
num = 2;
}
int num3 = 0;
for (num3 = 0; num3 != array.Length && ((array[num3] & 0xF) ^ 0xA) != 0; num3++)
{
}
num3++;
int num4 = array.Length - num - digest.GetDigestSize();
if (num4 - num3 <= 0)
{
throw new InvalidCipherTextException("malformed block");
}
if ((array[0] & 0x20) == 0)
{
fullMessage = true;
recoveredMessage = new byte[num4 - num3];
Array.Copy(array, num3, recoveredMessage, 0, recoveredMessage.Length);
}
else
{
fullMessage = false;
recoveredMessage = new byte[num4 - num3];
Array.Copy(array, num3, recoveredMessage, 0, recoveredMessage.Length);
}
preSig = signature;
preBlock = array;
digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length);
messageLength = recoveredMessage.Length;
recoveredMessage.CopyTo(mBuf, 0);
}
public virtual void Update(byte input)
{
digest.Update(input);
if (messageLength < mBuf.Length)
{
mBuf[messageLength] = input;
}
messageLength++;
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
while (length > 0 && messageLength < mBuf.Length)
{
Update(input[inOff]);
inOff++;
length--;
}
digest.BlockUpdate(input, inOff, length);
messageLength += length;
}
public virtual void Reset()
{
digest.Reset();
messageLength = 0;
ClearBlock(mBuf);
if (recoveredMessage != null)
{
ClearBlock(recoveredMessage);
}
recoveredMessage = null;
fullMessage = false;
if (preSig != null)
{
preSig = null;
ClearBlock(preBlock);
preBlock = null;
}
}
public virtual byte[] GenerateSignature()
{
int digestSize = digest.GetDigestSize();
int num = 0;
int num2 = 0;
if (trailer == 188)
{
num = 8;
num2 = block.Length - digestSize - 1;
digest.DoFinal(block, num2);
block[block.Length - 1] = 188;
}
else
{
num = 16;
num2 = block.Length - digestSize - 2;
digest.DoFinal(block, num2);
block[block.Length - 2] = (byte)((uint)trailer >> 8);
block[block.Length - 1] = (byte)trailer;
}
byte b = 0;
int num3 = (digestSize + messageLength) * 8 + num + 4 - keyBits;
if (num3 > 0)
{
int num4 = messageLength - (num3 + 7) / 8;
b = 96;
num2 -= num4;
Array.Copy(mBuf, 0, block, num2, num4);
}
else
{
b = 64;
num2 -= messageLength;
Array.Copy(mBuf, 0, block, num2, messageLength);
}
if (num2 - 1 > 0)
{
for (int num5 = num2 - 1; num5 != 0; num5--)
{
block[num5] = 187;
}
byte[] array2;
byte[] array = (array2 = block);
int num6 = num2 - 1;
nint num7 = num6;
array[num6] = (byte)(array2[num7] ^ 1);
block[0] = 11;
(array2 = block)[0] = (byte)(array2[0] | b);
}
else
{
block[0] = 10;
byte[] array2;
(array2 = block)[0] = (byte)(array2[0] | b);
}
byte[] result = cipher.ProcessBlock(block, 0, block.Length);
messageLength = 0;
ClearBlock(mBuf);
ClearBlock(block);
return result;
}
public virtual bool VerifySignature(byte[] signature)
{
byte[] array;
if (preSig == null)
{
try
{
array = cipher.ProcessBlock(signature, 0, signature.Length);
}
catch (Exception)
{
return false;
}
}
else
{
if (!Arrays.AreEqual(preSig, signature))
{
throw new InvalidOperationException("updateWithRecoveredMessage called on different signature");
}
array = preBlock;
preSig = null;
preBlock = null;
}
if (((array[0] & 0xC0) ^ 0x40) != 0)
{
return ReturnFalse(array);
}
if (((array[^1] & 0xF) ^ 0xC) != 0)
{
return ReturnFalse(array);
}
int num = 0;
if (((array[^1] & 0xFF) ^ 0xBC) == 0)
{
num = 1;
}
else
{
int num2 = ((array[^2] & 0xFF) << 8) | (array[^1] & 0xFF);
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("unrecognised hash in signature");
}
if (num2 != IsoTrailers.GetTrailer(digest))
{
throw new InvalidOperationException("signer initialised with wrong digest for trailer " + num2);
}
num = 2;
}
int i;
for (i = 0; i != array.Length && ((array[i] & 0xF) ^ 0xA) != 0; i++)
{
}
i++;
byte[] array2 = new byte[digest.GetDigestSize()];
int num3 = array.Length - num - array2.Length;
if (num3 - i <= 0)
{
return ReturnFalse(array);
}
if ((array[0] & 0x20) == 0)
{
fullMessage = true;
if (messageLength > num3 - i)
{
return ReturnFalse(array);
}
digest.Reset();
digest.BlockUpdate(array, i, num3 - i);
digest.DoFinal(array2, 0);
bool flag = true;
for (int j = 0; j != array2.Length; j++)
{
byte[] array4;
byte[] array3 = (array4 = array);
int num4 = num3 + j;
nint num5 = num4;
array3[num4] = (byte)(array4[num5] ^ array2[j]);
if (array[num3 + j] != 0)
{
flag = false;
}
}
if (!flag)
{
return ReturnFalse(array);
}
recoveredMessage = new byte[num3 - i];
Array.Copy(array, i, recoveredMessage, 0, recoveredMessage.Length);
}
else
{
fullMessage = false;
digest.DoFinal(array2, 0);
bool flag2 = true;
for (int k = 0; k != array2.Length; k++)
{
byte[] array4;
byte[] array5 = (array4 = array);
int num6 = num3 + k;
nint num5 = num6;
array5[num6] = (byte)(array4[num5] ^ array2[k]);
if (array[num3 + k] != 0)
{
flag2 = false;
}
}
if (!flag2)
{
return ReturnFalse(array);
}
recoveredMessage = new byte[num3 - i];
Array.Copy(array, i, recoveredMessage, 0, recoveredMessage.Length);
}
if (messageLength != 0 && !IsSameAs(mBuf, recoveredMessage))
{
return ReturnFalse(array);
}
ClearBlock(mBuf);
ClearBlock(array);
messageLength = 0;
return true;
}
private bool ReturnFalse(byte[] block)
{
messageLength = 0;
ClearBlock(mBuf);
ClearBlock(block);
return false;
}
public virtual bool HasFullMessage()
{
return fullMessage;
}
}

View File

@@ -0,0 +1,58 @@
using System.Collections;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Crypto.Signers;
public class IsoTrailers
{
public const int TRAILER_IMPLICIT = 188;
public const int TRAILER_RIPEMD160 = 12748;
public const int TRAILER_RIPEMD128 = 13004;
public const int TRAILER_SHA1 = 13260;
public const int TRAILER_SHA256 = 13516;
public const int TRAILER_SHA512 = 13772;
public const int TRAILER_SHA384 = 14028;
public const int TRAILER_WHIRLPOOL = 14284;
public const int TRAILER_SHA224 = 14540;
public const int TRAILER_SHA512_224 = 14796;
public const int TRAILER_SHA512_256 = 16588;
private static readonly IDictionary trailerMap = CreateTrailerMap();
private static IDictionary CreateTrailerMap()
{
IDictionary dictionary = Platform.CreateHashtable();
dictionary.Add("RIPEMD128", 13004);
dictionary.Add("RIPEMD160", 12748);
dictionary.Add("SHA-1", 13260);
dictionary.Add("SHA-224", 14540);
dictionary.Add("SHA-256", 13516);
dictionary.Add("SHA-384", 14028);
dictionary.Add("SHA-512", 13772);
dictionary.Add("SHA-512/224", 14796);
dictionary.Add("SHA-512/256", 16588);
dictionary.Add("Whirlpool", 14284);
return CollectionUtilities.ReadOnly(dictionary);
}
public static int GetTrailer(IDigest digest)
{
return (int)trailerMap[digest.AlgorithmName];
}
public static bool NoTrailerAvailable(IDigest digest)
{
return !trailerMap.Contains(digest.AlgorithmName);
}
}

View File

@@ -0,0 +1,57 @@
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class PlainDsaEncoding : IDsaEncoding
{
public static readonly PlainDsaEncoding Instance = new PlainDsaEncoding();
public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
{
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(n);
if (encoding.Length != unsignedByteLength * 2)
{
throw new ArgumentException("Encoding has incorrect length", "encoding");
}
return new BigInteger[2]
{
DecodeValue(n, encoding, 0, unsignedByteLength),
DecodeValue(n, encoding, unsignedByteLength, unsignedByteLength)
};
}
public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
{
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(n);
byte[] array = new byte[unsignedByteLength * 2];
EncodeValue(n, r, array, 0, unsignedByteLength);
EncodeValue(n, s, array, unsignedByteLength, unsignedByteLength);
return array;
}
protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
{
if (x.SignValue < 0 || x.CompareTo(n) >= 0)
{
throw new ArgumentException("Value out of range", "x");
}
return x;
}
protected virtual BigInteger DecodeValue(BigInteger n, byte[] buf, int off, int len)
{
return CheckValue(n, new BigInteger(1, buf, off, len));
}
protected virtual void EncodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len)
{
byte[] array = CheckValue(n, x).ToByteArrayUnsigned();
int num = System.Math.Max(0, array.Length - len);
int num2 = array.Length - num;
int num3 = len - num2;
Arrays.Fill(buf, off, off + num3, 0);
Array.Copy(array, num, buf, off + num3, num2);
}
}

View File

@@ -0,0 +1,276 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class PssSigner : ISigner
{
public const byte TrailerImplicit = 188;
private readonly IDigest contentDigest1;
private readonly IDigest contentDigest2;
private readonly IDigest mgfDigest;
private readonly IAsymmetricBlockCipher cipher;
private SecureRandom random;
private int hLen;
private int mgfhLen;
private int sLen;
private bool sSet;
private int emBits;
private byte[] salt;
private byte[] mDash;
private byte[] block;
private byte trailer;
public virtual string AlgorithmName => mgfDigest.AlgorithmName + "withRSAandMGF1";
public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest digest)
{
return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, 188);
}
public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, int saltLen, byte trailer)
{
return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer);
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest digest)
: this(cipher, digest, digest.GetDigestSize())
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest digest, int saltLen)
: this(cipher, digest, saltLen, 188)
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest digest, byte[] salt)
: this(cipher, digest, digest, digest, salt.Length, salt, 188)
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, int saltLen)
: this(cipher, contentDigest, mgfDigest, saltLen, 188)
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, byte[] salt)
: this(cipher, contentDigest, contentDigest, mgfDigest, salt.Length, salt, 188)
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest digest, int saltLen, byte trailer)
: this(cipher, digest, digest, saltLen, 188)
{
}
public PssSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, int saltLen, byte trailer)
: this(cipher, contentDigest, contentDigest, mgfDigest, saltLen, null, trailer)
{
}
private PssSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest1, IDigest contentDigest2, IDigest mgfDigest, int saltLen, byte[] salt, byte trailer)
{
this.cipher = cipher;
this.contentDigest1 = contentDigest1;
this.contentDigest2 = contentDigest2;
this.mgfDigest = mgfDigest;
hLen = contentDigest2.GetDigestSize();
mgfhLen = mgfDigest.GetDigestSize();
sLen = saltLen;
sSet = salt != null;
if (sSet)
{
this.salt = salt;
}
else
{
this.salt = new byte[saltLen];
}
mDash = new byte[8 + saltLen + hLen];
this.trailer = trailer;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
parameters = parametersWithRandom.Parameters;
random = parametersWithRandom.Random;
}
else if (forSigning)
{
random = new SecureRandom();
}
cipher.Init(forSigning, parameters);
RsaKeyParameters rsaKeyParameters = ((!(parameters is RsaBlindingParameters)) ? ((RsaKeyParameters)parameters) : ((RsaBlindingParameters)parameters).PublicKey);
emBits = rsaKeyParameters.Modulus.BitLength - 1;
if (emBits < 8 * hLen + 8 * sLen + 9)
{
throw new ArgumentException("key too small for specified hash and salt lengths");
}
block = new byte[(emBits + 7) / 8];
}
private void ClearBlock(byte[] block)
{
Array.Clear(block, 0, block.Length);
}
public virtual void Update(byte input)
{
contentDigest1.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
contentDigest1.BlockUpdate(input, inOff, length);
}
public virtual void Reset()
{
contentDigest1.Reset();
}
public virtual byte[] GenerateSignature()
{
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
if (sLen != 0)
{
if (!sSet)
{
random.NextBytes(salt);
}
salt.CopyTo(mDash, mDash.Length - sLen);
}
byte[] array = new byte[hLen];
contentDigest2.BlockUpdate(mDash, 0, mDash.Length);
contentDigest2.DoFinal(array, 0);
block[block.Length - sLen - 1 - hLen - 1] = 1;
salt.CopyTo(block, block.Length - sLen - hLen - 1);
byte[] array2 = MaskGeneratorFunction1(array, 0, array.Length, block.Length - hLen - 1);
byte[] array4;
for (int i = 0; i != array2.Length; i++)
{
byte[] array3 = (array4 = block);
int num = i;
nint num2 = num;
array3[num] = (byte)(array4[num2] ^ array2[i]);
}
(array4 = block)[0] = (byte)(array4[0] & (byte)(255 >> block.Length * 8 - emBits));
array.CopyTo(block, block.Length - hLen - 1);
block[block.Length - 1] = trailer;
byte[] result = cipher.ProcessBlock(block, 0, block.Length);
ClearBlock(block);
return result;
}
public virtual bool VerifySignature(byte[] signature)
{
contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen);
byte[] array = cipher.ProcessBlock(signature, 0, signature.Length);
array.CopyTo(block, block.Length - array.Length);
if (block[block.Length - 1] != trailer)
{
ClearBlock(block);
return false;
}
byte[] array2 = MaskGeneratorFunction1(block, block.Length - hLen - 1, hLen, block.Length - hLen - 1);
byte[] array4;
for (int i = 0; i != array2.Length; i++)
{
byte[] array3 = (array4 = block);
int num = i;
nint num2 = num;
array3[num] = (byte)(array4[num2] ^ array2[i]);
}
(array4 = block)[0] = (byte)(array4[0] & (byte)(255 >> block.Length * 8 - emBits));
for (int j = 0; j != block.Length - hLen - sLen - 2; j++)
{
if (block[j] != 0)
{
ClearBlock(block);
return false;
}
}
if (block[block.Length - hLen - sLen - 2] != 1)
{
ClearBlock(block);
return false;
}
if (sSet)
{
Array.Copy(salt, 0, mDash, mDash.Length - sLen, sLen);
}
else
{
Array.Copy(block, block.Length - sLen - hLen - 1, mDash, mDash.Length - sLen, sLen);
}
contentDigest2.BlockUpdate(mDash, 0, mDash.Length);
contentDigest2.DoFinal(mDash, mDash.Length - hLen);
int num3 = block.Length - hLen - 1;
for (int k = mDash.Length - hLen; k != mDash.Length; k++)
{
if ((block[num3] ^ mDash[k]) != 0)
{
ClearBlock(mDash);
ClearBlock(block);
return false;
}
num3++;
}
ClearBlock(mDash);
ClearBlock(block);
return true;
}
private void ItoOSP(int i, byte[] sp)
{
sp[0] = (byte)((uint)i >> 24);
sp[1] = (byte)((uint)i >> 16);
sp[2] = (byte)((uint)i >> 8);
sp[3] = (byte)i;
}
private byte[] MaskGeneratorFunction1(byte[] Z, int zOff, int zLen, int length)
{
byte[] array = new byte[length];
byte[] array2 = new byte[mgfhLen];
byte[] array3 = new byte[4];
int i = 0;
mgfDigest.Reset();
for (; i < length / mgfhLen; i++)
{
ItoOSP(i, array3);
mgfDigest.BlockUpdate(Z, zOff, zLen);
mgfDigest.BlockUpdate(array3, 0, array3.Length);
mgfDigest.DoFinal(array2, 0);
array2.CopyTo(array, i * mgfhLen);
}
if (i * mgfhLen < length)
{
ItoOSP(i, array3);
mgfDigest.BlockUpdate(Z, zOff, zLen);
mgfDigest.BlockUpdate(array3, 0, array3.Length);
mgfDigest.DoFinal(array2, 0);
Array.Copy(array2, 0, array, i * mgfhLen, array.Length - i * mgfhLen);
}
return array;
}
}

View File

@@ -0,0 +1,37 @@
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class RandomDsaKCalculator : IDsaKCalculator
{
private BigInteger q;
private SecureRandom random;
public virtual bool IsDeterministic => false;
public virtual void Init(BigInteger n, SecureRandom random)
{
q = n;
this.random = random;
}
public virtual void Init(BigInteger n, BigInteger d, byte[] message)
{
throw new InvalidOperationException("Operation not supported");
}
public virtual BigInteger NextK()
{
int bitLength = q.BitLength;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(bitLength, random);
}
while (bigInteger.SignValue < 1 || bigInteger.CompareTo(q) >= 0);
return bigInteger;
}
}

View File

@@ -0,0 +1,174 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class RsaDigestSigner : ISigner
{
private readonly IAsymmetricBlockCipher rsaEngine;
private readonly AlgorithmIdentifier algId;
private readonly IDigest digest;
private bool forSigning;
private static readonly IDictionary oidMap;
public virtual string AlgorithmName => digest.AlgorithmName + "withRSA";
static RsaDigestSigner()
{
oidMap = Platform.CreateHashtable();
oidMap["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
oidMap["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
oidMap["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
oidMap["SHA-1"] = X509ObjectIdentifiers.IdSha1;
oidMap["SHA-224"] = NistObjectIdentifiers.IdSha224;
oidMap["SHA-256"] = NistObjectIdentifiers.IdSha256;
oidMap["SHA-384"] = NistObjectIdentifiers.IdSha384;
oidMap["SHA-512"] = NistObjectIdentifiers.IdSha512;
oidMap["MD2"] = PkcsObjectIdentifiers.MD2;
oidMap["MD4"] = PkcsObjectIdentifiers.MD4;
oidMap["MD5"] = PkcsObjectIdentifiers.MD5;
}
public RsaDigestSigner(IDigest digest)
: this(digest, (DerObjectIdentifier)oidMap[digest.AlgorithmName])
{
}
public RsaDigestSigner(IDigest digest, DerObjectIdentifier digestOid)
: this(digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
{
}
public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId)
: this(new RsaCoreEngine(), digest, algId)
{
}
public RsaDigestSigner(IRsa rsa, IDigest digest, DerObjectIdentifier digestOid)
: this(rsa, digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
{
}
public RsaDigestSigner(IRsa rsa, IDigest digest, AlgorithmIdentifier algId)
: this(new RsaBlindedEngine(rsa), digest, algId)
{
}
public RsaDigestSigner(IAsymmetricBlockCipher rsaEngine, IDigest digest, AlgorithmIdentifier algId)
{
this.rsaEngine = new Pkcs1Encoding(rsaEngine);
this.digest = digest;
this.algId = algId;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter asymmetricKeyParameter = ((!(parameters is ParametersWithRandom)) ? ((AsymmetricKeyParameter)parameters) : ((AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters));
if (forSigning && !asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Signing requires private key.");
}
if (!forSigning && asymmetricKeyParameter.IsPrivate)
{
throw new InvalidKeyException("Verification requires public key.");
}
Reset();
rsaEngine.Init(forSigning, parameters);
}
public virtual void Update(byte input)
{
digest.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
public virtual byte[] GenerateSignature()
{
if (!forSigning)
{
throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation.");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
byte[] array2 = DerEncode(array);
return rsaEngine.ProcessBlock(array2, 0, array2.Length);
}
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
{
throw new InvalidOperationException("RsaDigestSigner not initialised for verification");
}
byte[] array = new byte[digest.GetDigestSize()];
digest.DoFinal(array, 0);
byte[] array2;
byte[] array3;
try
{
array2 = rsaEngine.ProcessBlock(signature, 0, signature.Length);
array3 = DerEncode(array);
}
catch (Exception)
{
return false;
}
if (array2.Length == array3.Length)
{
return Arrays.ConstantTimeAreEqual(array2, array3);
}
if (array2.Length == array3.Length - 2)
{
int num = array2.Length - array.Length - 2;
int num2 = array3.Length - array.Length - 2;
byte[] array4;
(array4 = array3)[1] = (byte)(array4[1] - 2);
(array4 = array3)[3] = (byte)(array4[3] - 2);
int num3 = 0;
for (int i = 0; i < array.Length; i++)
{
num3 |= array2[num + i] ^ array3[num2 + i];
}
for (int j = 0; j < num; j++)
{
num3 |= array2[j] ^ array3[j];
}
return num3 == 0;
}
return false;
}
public virtual void Reset()
{
digest.Reset();
}
private byte[] DerEncode(byte[] hash)
{
if (algId == null)
{
return hash;
}
DigestInfo digestInfo = new DigestInfo(algId, hash);
return digestInfo.GetDerEncoded();
}
}

View File

@@ -0,0 +1,211 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Crypto.Signers;
public class SM2Signer : ISigner
{
private readonly IDsaKCalculator kCalculator = new RandomDsaKCalculator();
private readonly SM3Digest digest = new SM3Digest();
private readonly IDsaEncoding encoding;
private ECDomainParameters ecParams;
private ECPoint pubPoint;
private ECKeyParameters ecKey;
private byte[] z;
public virtual string AlgorithmName => "SM2Sign";
public SM2Signer()
{
encoding = StandardDsaEncoding.Instance;
}
public SM2Signer(IDsaEncoding encoding)
{
this.encoding = encoding;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
ICipherParameters cipherParameters;
byte[] userID;
if (parameters is ParametersWithID)
{
cipherParameters = ((ParametersWithID)parameters).Parameters;
userID = ((ParametersWithID)parameters).GetID();
}
else
{
cipherParameters = parameters;
userID = Hex.Decode("31323334353637383132333435363738");
}
if (forSigning)
{
if (cipherParameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)cipherParameters;
ecKey = (ECKeyParameters)parametersWithRandom.Parameters;
ecParams = ecKey.Parameters;
kCalculator.Init(ecParams.N, parametersWithRandom.Random);
}
else
{
ecKey = (ECKeyParameters)cipherParameters;
ecParams = ecKey.Parameters;
kCalculator.Init(ecParams.N, new SecureRandom());
}
pubPoint = CreateBasePointMultiplier().Multiply(ecParams.G, ((ECPrivateKeyParameters)ecKey).D).Normalize();
}
else
{
ecKey = (ECKeyParameters)cipherParameters;
ecParams = ecKey.Parameters;
pubPoint = ((ECPublicKeyParameters)ecKey).Q;
}
digest.Reset();
z = GetZ(userID);
digest.BlockUpdate(z, 0, z.Length);
}
public virtual void Update(byte b)
{
digest.Update(b);
}
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
digest.BlockUpdate(buf, off, len);
}
public virtual bool VerifySignature(byte[] signature)
{
try
{
BigInteger[] array = encoding.Decode(ecParams.N, signature);
return VerifySignature(array[0], array[1]);
}
catch (Exception)
{
}
return false;
}
public virtual void Reset()
{
if (z != null)
{
digest.Reset();
digest.BlockUpdate(z, 0, z.Length);
}
}
public virtual byte[] GenerateSignature()
{
byte[] message = DigestUtilities.DoFinal(digest);
BigInteger n = ecParams.N;
BigInteger bigInteger = CalculateE(message);
BigInteger d = ((ECPrivateKeyParameters)ecKey).D;
ECMultiplier eCMultiplier = CreateBasePointMultiplier();
BigInteger bigInteger3;
BigInteger val;
while (true)
{
BigInteger bigInteger2 = kCalculator.NextK();
ECPoint eCPoint = eCMultiplier.Multiply(ecParams.G, bigInteger2).Normalize();
bigInteger3 = bigInteger.Add(eCPoint.AffineXCoord.ToBigInteger()).Mod(n);
if (bigInteger3.SignValue != 0 && !bigInteger3.Add(bigInteger2).Equals(n))
{
BigInteger bigInteger4 = d.Add(BigInteger.One).ModInverse(n);
val = bigInteger2.Subtract(bigInteger3.Multiply(d)).Mod(n);
val = bigInteger4.Multiply(val).Mod(n);
if (val.SignValue != 0)
{
break;
}
}
}
try
{
return encoding.Encode(ecParams.N, bigInteger3, val);
}
catch (Exception ex)
{
throw new CryptoException("unable to encode signature: " + ex.Message, ex);
}
}
private bool VerifySignature(BigInteger r, BigInteger s)
{
BigInteger n = ecParams.N;
if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
{
return false;
}
if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
{
return false;
}
byte[] message = DigestUtilities.DoFinal(digest);
BigInteger bigInteger = CalculateE(message);
BigInteger bigInteger2 = r.Add(s).Mod(n);
if (bigInteger2.SignValue == 0)
{
return false;
}
ECPoint q = ((ECPublicKeyParameters)ecKey).Q;
ECPoint eCPoint = ECAlgorithms.SumOfTwoMultiplies(ecParams.G, s, q, bigInteger2).Normalize();
if (eCPoint.IsInfinity)
{
return false;
}
return r.Equals(bigInteger.Add(eCPoint.AffineXCoord.ToBigInteger()).Mod(n));
}
private byte[] GetZ(byte[] userID)
{
AddUserID(digest, userID);
AddFieldElement(digest, ecParams.Curve.A);
AddFieldElement(digest, ecParams.Curve.B);
AddFieldElement(digest, ecParams.G.AffineXCoord);
AddFieldElement(digest, ecParams.G.AffineYCoord);
AddFieldElement(digest, pubPoint.AffineXCoord);
AddFieldElement(digest, pubPoint.AffineYCoord);
return DigestUtilities.DoFinal(digest);
}
private void AddUserID(IDigest digest, byte[] userID)
{
int num = userID.Length * 8;
digest.Update((byte)(num >> 8));
digest.Update((byte)num);
digest.BlockUpdate(userID, 0, userID.Length);
}
private void AddFieldElement(IDigest digest, ECFieldElement v)
{
byte[] encoded = v.GetEncoded();
digest.BlockUpdate(encoded, 0, encoded.Length);
}
protected virtual BigInteger CalculateE(byte[] message)
{
return new BigInteger(1, message);
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
}

View File

@@ -0,0 +1,51 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class StandardDsaEncoding : IDsaEncoding
{
public static readonly StandardDsaEncoding Instance = new StandardDsaEncoding();
public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
{
Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(encoding);
if (asn1Sequence.Count == 2)
{
BigInteger bigInteger = DecodeValue(n, asn1Sequence, 0);
BigInteger bigInteger2 = DecodeValue(n, asn1Sequence, 1);
byte[] a = Encode(n, bigInteger, bigInteger2);
if (Arrays.AreEqual(a, encoding))
{
return new BigInteger[2] { bigInteger, bigInteger2 };
}
}
throw new ArgumentException("Malformed signature", "encoding");
}
public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
{
return new DerSequence(EncodeValue(n, r), EncodeValue(n, s)).GetEncoded("DER");
}
protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
{
if (x.SignValue < 0 || (n != null && x.CompareTo(n) >= 0))
{
throw new ArgumentException("Value out of range", "x");
}
return x;
}
protected virtual BigInteger DecodeValue(BigInteger n, Asn1Sequence s, int pos)
{
return CheckValue(n, ((DerInteger)s[pos]).Value);
}
protected virtual DerInteger EncodeValue(BigInteger n, BigInteger x)
{
return new DerInteger(CheckValue(n, x));
}
}

View File

@@ -0,0 +1,168 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Signers;
public class X931Signer : ISigner
{
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_IMPLICIT = 188;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_RIPEMD160 = 12748;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_RIPEMD128 = 13004;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA1 = 13260;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA256 = 13516;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA512 = 13772;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA384 = 14028;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_WHIRLPOOL = 14284;
[Obsolete("Use 'IsoTrailers' instead")]
public const int TRAILER_SHA224 = 14540;
private IDigest digest;
private IAsymmetricBlockCipher cipher;
private RsaKeyParameters kParam;
private int trailer;
private int keyBits;
private byte[] block;
public virtual string AlgorithmName => digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31";
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
{
this.cipher = cipher;
this.digest = digest;
if (isImplicit)
{
trailer = 188;
return;
}
if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("no valid trailer", "digest");
}
trailer = IsoTrailers.GetTrailer(digest);
}
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
: this(cipher, digest, isImplicit: false)
{
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
kParam = (RsaKeyParameters)parameters;
cipher.Init(forSigning, kParam);
keyBits = kParam.Modulus.BitLength;
block = new byte[(keyBits + 7) / 8];
Reset();
}
private void ClearBlock(byte[] block)
{
Array.Clear(block, 0, block.Length);
}
public virtual void Update(byte b)
{
digest.Update(b);
}
public virtual void BlockUpdate(byte[] input, int off, int len)
{
digest.BlockUpdate(input, off, len);
}
public virtual void Reset()
{
digest.Reset();
}
public virtual byte[] GenerateSignature()
{
CreateSignatureBlock();
BigInteger bigInteger = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
ClearBlock(block);
bigInteger = bigInteger.Min(kParam.Modulus.Subtract(bigInteger));
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
return BigIntegers.AsUnsignedByteArray(unsignedByteLength, bigInteger);
}
private void CreateSignatureBlock()
{
int digestSize = digest.GetDigestSize();
int num;
if (trailer == 188)
{
num = block.Length - digestSize - 1;
digest.DoFinal(block, num);
block[block.Length - 1] = 188;
}
else
{
num = block.Length - digestSize - 2;
digest.DoFinal(block, num);
block[block.Length - 2] = (byte)(trailer >> 8);
block[block.Length - 1] = (byte)trailer;
}
block[0] = 107;
for (int num2 = num - 2; num2 != 0; num2--)
{
block[num2] = 187;
}
block[num - 1] = 186;
}
public virtual bool VerifySignature(byte[] signature)
{
try
{
block = cipher.ProcessBlock(signature, 0, signature.Length);
}
catch (Exception)
{
return false;
}
BigInteger bigInteger = new BigInteger(1, block);
BigInteger n;
if ((bigInteger.IntValue & 0xF) == 12)
{
n = bigInteger;
}
else
{
bigInteger = kParam.Modulus.Subtract(bigInteger);
if ((bigInteger.IntValue & 0xF) != 12)
{
return false;
}
n = bigInteger;
}
CreateSignatureBlock();
byte[] b = BigIntegers.AsUnsignedByteArray(block.Length, n);
bool result = Arrays.ConstantTimeAreEqual(block, b);
ClearBlock(block);
ClearBlock(b);
return result;
}
}