123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- using Org.BouncyCastle.Crypto;
- 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
- {
- /**
- * GOST R 34.10-2001 Signature Algorithm
- */
- public class ECGost3410Signer
- : IDsa
- {
- private ECKeyParameters key;
- private SecureRandom random;
- public virtual string AlgorithmName
- {
- get { return "ECGOST3410"; }
- }
- public virtual void Init(
- bool forSigning,
- ICipherParameters parameters)
- {
- if (forSigning)
- {
- if (parameters is ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)parameters;
- this.random = rParam.Random;
- parameters = rParam.Parameters;
- }
- else
- {
- this.random = new SecureRandom();
- }
- if (!(parameters is ECPrivateKeyParameters))
- throw new InvalidKeyException("EC private key required for signing");
- this.key = (ECPrivateKeyParameters) parameters;
- }
- else
- {
- if (!(parameters is ECPublicKeyParameters))
- throw new InvalidKeyException("EC public key required for verification");
- this.key = (ECPublicKeyParameters)parameters;
- }
- }
- /**
- * generate a signature for the given message using the key we were
- * initialised with. For conventional GOST3410 the message should be a GOST3411
- * hash of the message of interest.
- *
- * @param message the message that will be verified later.
- */
- public virtual BigInteger[] GenerateSignature(
- byte[] message)
- {
- byte[] mRev = new byte[message.Length]; // conversion is little-endian
- for (int i = 0; i != mRev.Length; i++)
- {
- mRev[i] = message[mRev.Length - 1 - i];
- }
- BigInteger e = new BigInteger(1, mRev);
- ECDomainParameters ec = key.Parameters;
- BigInteger n = ec.N;
- BigInteger d = ((ECPrivateKeyParameters)key).D;
- BigInteger r, s = null;
- ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
- do // generate s
- {
- BigInteger k;
- do // generate r
- {
- do
- {
- k = new BigInteger(n.BitLength, random);
- }
- while (k.SignValue == 0);
- ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize();
- r = p.AffineXCoord.ToBigInteger().Mod(n);
- }
- while (r.SignValue == 0);
- s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n);
- }
- while (s.SignValue == 0);
- return new BigInteger[]{ r, s };
- }
- /**
- * return true if the value r and s represent a GOST3410 signature for
- * the passed in message (for standard GOST3410 the message should be
- * a GOST3411 hash of the real message to be verified).
- */
- public virtual bool VerifySignature(
- byte[] message,
- BigInteger r,
- BigInteger s)
- {
- byte[] mRev = new byte[message.Length]; // conversion is little-endian
- for (int i = 0; i != mRev.Length; i++)
- {
- mRev[i] = message[mRev.Length - 1 - i];
- }
- BigInteger e = new BigInteger(1, mRev);
- BigInteger n = key.Parameters.N;
- // r in the range [1,n-1]
- if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
- {
- return false;
- }
- // s in the range [1,n-1]
- if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
- {
- return false;
- }
- BigInteger v = e.ModInverse(n);
- BigInteger z1 = s.Multiply(v).Mod(n);
- BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);
- ECPoint G = key.Parameters.G; // P
- ECPoint Q = ((ECPublicKeyParameters)key).Q;
- ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize();
- if (point.IsInfinity)
- return false;
- BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n);
- return R.Equals(r);
- }
- protected virtual ECMultiplier CreateBasePointMultiplier()
- {
- return new FixedPointCombMultiplier();
- }
- }
- }
- #endif
|