ECGOST3410Signer.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  10. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
  11. {
  12. /**
  13. * GOST R 34.10-2001 Signature Algorithm
  14. */
  15. public class ECGost3410Signer
  16. : IDsaExt
  17. {
  18. private ECKeyParameters key;
  19. private SecureRandom random;
  20. public virtual string AlgorithmName
  21. {
  22. get { return "ECGOST3410"; }
  23. }
  24. public virtual void Init(
  25. bool forSigning,
  26. ICipherParameters parameters)
  27. {
  28. if (forSigning)
  29. {
  30. if (parameters is ParametersWithRandom)
  31. {
  32. ParametersWithRandom rParam = (ParametersWithRandom)parameters;
  33. this.random = rParam.Random;
  34. parameters = rParam.Parameters;
  35. }
  36. else
  37. {
  38. this.random = new SecureRandom();
  39. }
  40. if (!(parameters is ECPrivateKeyParameters))
  41. throw new InvalidKeyException("EC private key required for signing");
  42. this.key = (ECPrivateKeyParameters) parameters;
  43. }
  44. else
  45. {
  46. if (!(parameters is ECPublicKeyParameters))
  47. throw new InvalidKeyException("EC public key required for verification");
  48. this.key = (ECPublicKeyParameters)parameters;
  49. }
  50. }
  51. public virtual BigInteger Order
  52. {
  53. get { return key.Parameters.N; }
  54. }
  55. /**
  56. * generate a signature for the given message using the key we were
  57. * initialised with. For conventional GOST3410 the message should be a GOST3411
  58. * hash of the message of interest.
  59. *
  60. * @param message the message that will be verified later.
  61. */
  62. public virtual BigInteger[] GenerateSignature(
  63. byte[] message)
  64. {
  65. byte[] mRev = new byte[message.Length]; // conversion is little-endian
  66. for (int i = 0; i != mRev.Length; i++)
  67. {
  68. mRev[i] = message[mRev.Length - 1 - i];
  69. }
  70. BigInteger e = new BigInteger(1, mRev);
  71. ECDomainParameters ec = key.Parameters;
  72. BigInteger n = ec.N;
  73. BigInteger d = ((ECPrivateKeyParameters)key).D;
  74. BigInteger r, s = null;
  75. ECMultiplier basePointMultiplier = CreateBasePointMultiplier();
  76. do // generate s
  77. {
  78. BigInteger k;
  79. do // generate r
  80. {
  81. do
  82. {
  83. k = new BigInteger(n.BitLength, random);
  84. }
  85. while (k.SignValue == 0);
  86. ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize();
  87. r = p.AffineXCoord.ToBigInteger().Mod(n);
  88. }
  89. while (r.SignValue == 0);
  90. s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n);
  91. }
  92. while (s.SignValue == 0);
  93. return new BigInteger[]{ r, s };
  94. }
  95. /**
  96. * return true if the value r and s represent a GOST3410 signature for
  97. * the passed in message (for standard GOST3410 the message should be
  98. * a GOST3411 hash of the real message to be verified).
  99. */
  100. public virtual bool VerifySignature(
  101. byte[] message,
  102. BigInteger r,
  103. BigInteger s)
  104. {
  105. byte[] mRev = new byte[message.Length]; // conversion is little-endian
  106. for (int i = 0; i != mRev.Length; i++)
  107. {
  108. mRev[i] = message[mRev.Length - 1 - i];
  109. }
  110. BigInteger e = new BigInteger(1, mRev);
  111. BigInteger n = key.Parameters.N;
  112. // r in the range [1,n-1]
  113. if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
  114. {
  115. return false;
  116. }
  117. // s in the range [1,n-1]
  118. if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
  119. {
  120. return false;
  121. }
  122. BigInteger v = e.ModInverse(n);
  123. BigInteger z1 = s.Multiply(v).Mod(n);
  124. BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);
  125. ECPoint G = key.Parameters.G; // P
  126. ECPoint Q = ((ECPublicKeyParameters)key).Q;
  127. ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize();
  128. if (point.IsInfinity)
  129. return false;
  130. BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n);
  131. return R.Equals(r);
  132. }
  133. protected virtual ECMultiplier CreateBasePointMultiplier()
  134. {
  135. return new FixedPointCombMultiplier();
  136. }
  137. }
  138. }
  139. #pragma warning restore
  140. #endif