HMacDsaKCalculator.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  9. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
  10. {
  11. /**
  12. * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979.
  13. */
  14. public class HMacDsaKCalculator
  15. : IDsaKCalculator
  16. {
  17. private readonly HMac hMac;
  18. private readonly byte[] K;
  19. private readonly byte[] V;
  20. private BigInteger n;
  21. /**
  22. * Base constructor.
  23. *
  24. * @param digest digest to build the HMAC on.
  25. */
  26. public HMacDsaKCalculator(IDigest digest)
  27. {
  28. this.hMac = new HMac(digest);
  29. this.V = new byte[hMac.GetMacSize()];
  30. this.K = new byte[hMac.GetMacSize()];
  31. }
  32. public virtual bool IsDeterministic
  33. {
  34. get { return true; }
  35. }
  36. public virtual void Init(BigInteger n, SecureRandom random)
  37. {
  38. throw new InvalidOperationException("Operation not supported");
  39. }
  40. public void Init(BigInteger n, BigInteger d, byte[] message)
  41. {
  42. this.n = n;
  43. Arrays.Fill(V, (byte)0x01);
  44. Arrays.Fill(K, (byte)0);
  45. int size = BigIntegers.GetUnsignedByteLength(n);
  46. byte[] x = new byte[size];
  47. byte[] dVal = BigIntegers.AsUnsignedByteArray(d);
  48. Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length);
  49. byte[] m = new byte[size];
  50. BigInteger mInt = BitsToInt(message);
  51. if (mInt.CompareTo(n) >= 0)
  52. {
  53. mInt = mInt.Subtract(n);
  54. }
  55. byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt);
  56. Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length);
  57. hMac.Init(new KeyParameter(K));
  58. hMac.BlockUpdate(V, 0, V.Length);
  59. hMac.Update((byte)0x00);
  60. hMac.BlockUpdate(x, 0, x.Length);
  61. hMac.BlockUpdate(m, 0, m.Length);
  62. hMac.DoFinal(K, 0);
  63. hMac.Init(new KeyParameter(K));
  64. hMac.BlockUpdate(V, 0, V.Length);
  65. hMac.DoFinal(V, 0);
  66. hMac.BlockUpdate(V, 0, V.Length);
  67. hMac.Update((byte)0x01);
  68. hMac.BlockUpdate(x, 0, x.Length);
  69. hMac.BlockUpdate(m, 0, m.Length);
  70. hMac.DoFinal(K, 0);
  71. hMac.Init(new KeyParameter(K));
  72. hMac.BlockUpdate(V, 0, V.Length);
  73. hMac.DoFinal(V, 0);
  74. }
  75. public virtual BigInteger NextK()
  76. {
  77. byte[] t = new byte[BigIntegers.GetUnsignedByteLength(n)];
  78. for (;;)
  79. {
  80. int tOff = 0;
  81. while (tOff < t.Length)
  82. {
  83. hMac.BlockUpdate(V, 0, V.Length);
  84. hMac.DoFinal(V, 0);
  85. int len = System.Math.Min(t.Length - tOff, V.Length);
  86. Array.Copy(V, 0, t, tOff, len);
  87. tOff += len;
  88. }
  89. BigInteger k = BitsToInt(t);
  90. if (k.SignValue > 0 && k.CompareTo(n) < 0)
  91. {
  92. return k;
  93. }
  94. hMac.BlockUpdate(V, 0, V.Length);
  95. hMac.Update((byte)0x00);
  96. hMac.DoFinal(K, 0);
  97. hMac.Init(new KeyParameter(K));
  98. hMac.BlockUpdate(V, 0, V.Length);
  99. hMac.DoFinal(V, 0);
  100. }
  101. }
  102. private BigInteger BitsToInt(byte[] t)
  103. {
  104. BigInteger v = new BigInteger(1, t);
  105. if (t.Length * 8 > n.BitLength)
  106. {
  107. v = v.ShiftRight(t.Length * 8 - n.BitLength);
  108. }
  109. return v;
  110. }
  111. }
  112. }
  113. #pragma warning restore
  114. #endif