GOST3410Signer.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
  9. {
  10. /**
  11. * Gost R 34.10-94 Signature Algorithm
  12. */
  13. public class Gost3410Signer
  14. : IDsa
  15. {
  16. private Gost3410KeyParameters key;
  17. private SecureRandom random;
  18. public virtual string AlgorithmName
  19. {
  20. get { return "GOST3410"; }
  21. }
  22. public virtual void Init(bool forSigning, ICipherParameters parameters)
  23. {
  24. if (forSigning)
  25. {
  26. if (parameters is ParametersWithRandom rParam)
  27. {
  28. this.random = rParam.Random;
  29. parameters = rParam.Parameters;
  30. }
  31. else
  32. {
  33. this.random = CryptoServicesRegistrar.GetSecureRandom();
  34. }
  35. if (!(parameters is Gost3410PrivateKeyParameters))
  36. throw new InvalidKeyException("GOST3410 private key required for signing");
  37. this.key = (Gost3410PrivateKeyParameters) parameters;
  38. }
  39. else
  40. {
  41. if (!(parameters is Gost3410PublicKeyParameters))
  42. throw new InvalidKeyException("GOST3410 public key required for signing");
  43. this.key = (Gost3410PublicKeyParameters) parameters;
  44. }
  45. }
  46. public virtual BigInteger Order
  47. {
  48. get { return key.Parameters.Q; }
  49. }
  50. /**
  51. * generate a signature for the given message using the key we were
  52. * initialised with. For conventional Gost3410 the message should be a Gost3411
  53. * hash of the message of interest.
  54. *
  55. * @param message the message that will be verified later.
  56. */
  57. public virtual BigInteger[] GenerateSignature(
  58. byte[] message)
  59. {
  60. byte[] mRev = Arrays.Reverse(message); // conversion is little-endian
  61. BigInteger m = new BigInteger(1, mRev);
  62. Gost3410Parameters parameters = key.Parameters;
  63. BigInteger k;
  64. do
  65. {
  66. k = new BigInteger(parameters.Q.BitLength, random);
  67. }
  68. while (k.CompareTo(parameters.Q) >= 0);
  69. BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q);
  70. BigInteger s = k.Multiply(m).
  71. Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)).
  72. Mod(parameters.Q);
  73. return new BigInteger[]{ r, s };
  74. }
  75. /**
  76. * return true if the value r and s represent a Gost3410 signature for
  77. * the passed in message for standard Gost3410 the message should be a
  78. * Gost3411 hash of the real message to be verified.
  79. */
  80. public virtual bool VerifySignature(
  81. byte[] message,
  82. BigInteger r,
  83. BigInteger s)
  84. {
  85. byte[] mRev = Arrays.Reverse(message); // conversion is little-endian
  86. BigInteger m = new BigInteger(1, mRev);
  87. Gost3410Parameters parameters = key.Parameters;
  88. if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0)
  89. {
  90. return false;
  91. }
  92. if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0)
  93. {
  94. return false;
  95. }
  96. BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q);
  97. BigInteger z1 = s.Multiply(v).Mod(parameters.Q);
  98. BigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q);
  99. z1 = parameters.A.ModPow(z1, parameters.P);
  100. z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P);
  101. BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q);
  102. return u.Equals(r);
  103. }
  104. }
  105. }
  106. #pragma warning restore
  107. #endif