GOST3410Signer.cs 3.4 KB

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