HMacDsaKCalculator.cs 3.8 KB

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