DsaSigner.cs 4.8 KB

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