init commit
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user