DsaSigner.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
  9. {
  10. /**
  11. * The Digital Signature Algorithm - as described in "Handbook of Applied
  12. * Cryptography", pages 452 - 453.
  13. */
  14. public class DsaSigner
  15. : IDsaExt
  16. {
  17. protected readonly IDsaKCalculator kCalculator;
  18. protected DsaKeyParameters key = null;
  19. protected SecureRandom random = null;
  20. /**
  21. * Default configuration, random K values.
  22. */
  23. public DsaSigner()
  24. {
  25. this.kCalculator = new RandomDsaKCalculator();
  26. }
  27. /**
  28. * Configuration with an alternate, possibly deterministic calculator of K.
  29. *
  30. * @param kCalculator a K value calculator.
  31. */
  32. public DsaSigner(IDsaKCalculator kCalculator)
  33. {
  34. this.kCalculator = kCalculator;
  35. }
  36. public virtual string AlgorithmName
  37. {
  38. get { return "DSA"; }
  39. }
  40. public virtual void Init(bool forSigning, ICipherParameters parameters)
  41. {
  42. SecureRandom providedRandom = null;
  43. if (forSigning)
  44. {
  45. if (parameters is ParametersWithRandom)
  46. {
  47. ParametersWithRandom rParam = (ParametersWithRandom)parameters;
  48. providedRandom = rParam.Random;
  49. parameters = rParam.Parameters;
  50. }
  51. if (!(parameters is DsaPrivateKeyParameters))
  52. throw new InvalidKeyException("DSA private key required for signing");
  53. this.key = (DsaPrivateKeyParameters)parameters;
  54. }
  55. else
  56. {
  57. if (!(parameters is DsaPublicKeyParameters))
  58. throw new InvalidKeyException("DSA public key required for verification");
  59. this.key = (DsaPublicKeyParameters)parameters;
  60. }
  61. this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom);
  62. }
  63. public virtual BigInteger Order
  64. {
  65. get { return key.Parameters.Q; }
  66. }
  67. /**
  68. * Generate a signature for the given message using the key we were
  69. * initialised with. For conventional DSA the message should be a SHA-1
  70. * hash of the message of interest.
  71. *
  72. * @param message the message that will be verified later.
  73. */
  74. public virtual BigInteger[] GenerateSignature(byte[] message)
  75. {
  76. DsaParameters parameters = key.Parameters;
  77. BigInteger q = parameters.Q;
  78. BigInteger m = CalculateE(q, message);
  79. BigInteger x = ((DsaPrivateKeyParameters)key).X;
  80. if (kCalculator.IsDeterministic)
  81. {
  82. kCalculator.Init(q, x, message);
  83. }
  84. else
  85. {
  86. kCalculator.Init(q, random);
  87. }
  88. BigInteger k = kCalculator.NextK();
  89. BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q);
  90. k = BigIntegers.ModOddInverse(q, k).Multiply(m.Add(x.Multiply(r)));
  91. BigInteger s = k.Mod(q);
  92. return new BigInteger[]{ r, s };
  93. }
  94. /**
  95. * return true if the value r and s represent a DSA signature for
  96. * the passed in message for standard DSA the message should be a
  97. * SHA-1 hash of the real message to be verified.
  98. */
  99. public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
  100. {
  101. DsaParameters parameters = key.Parameters;
  102. BigInteger q = parameters.Q;
  103. BigInteger m = CalculateE(q, message);
  104. if (r.SignValue <= 0 || q.CompareTo(r) <= 0)
  105. {
  106. return false;
  107. }
  108. if (s.SignValue <= 0 || q.CompareTo(s) <= 0)
  109. {
  110. return false;
  111. }
  112. BigInteger w = BigIntegers.ModOddInverseVar(q, s);
  113. BigInteger u1 = m.Multiply(w).Mod(q);
  114. BigInteger u2 = r.Multiply(w).Mod(q);
  115. BigInteger p = parameters.P;
  116. u1 = parameters.G.ModPow(u1, p);
  117. u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p);
  118. BigInteger v = u1.Multiply(u2).Mod(p).Mod(q);
  119. return v.Equals(r);
  120. }
  121. protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
  122. {
  123. int length = System.Math.Min(message.Length, n.BitLength / 8);
  124. return new BigInteger(1, message, 0, length);
  125. }
  126. protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
  127. {
  128. return !needed ? null : (provided != null) ? provided : new SecureRandom();
  129. }
  130. }
  131. }
  132. #pragma warning restore
  133. #endif