Mod.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Diagnostics;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw
  9. {
  10. internal abstract class Mod
  11. {
  12. private static readonly SecureRandom RandomSource = new SecureRandom();
  13. public static void Invert(uint[] p, uint[] x, uint[] z)
  14. {
  15. int len = p.Length;
  16. if (Nat.IsZero(len, x))
  17. throw new ArgumentException("cannot be 0", "x");
  18. if (Nat.IsOne(len, x))
  19. {
  20. Array.Copy(x, 0, z, 0, len);
  21. return;
  22. }
  23. uint[] u = Nat.Copy(len, x);
  24. uint[] a = Nat.Create(len);
  25. a[0] = 1;
  26. int ac = 0;
  27. if ((u[0] & 1) == 0)
  28. {
  29. InversionStep(p, u, len, a, ref ac);
  30. }
  31. if (Nat.IsOne(len, u))
  32. {
  33. InversionResult(p, ac, a, z);
  34. return;
  35. }
  36. uint[] v = Nat.Copy(len, p);
  37. uint[] b = Nat.Create(len);
  38. int bc = 0;
  39. int uvLen = len;
  40. for (;;)
  41. {
  42. while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0)
  43. {
  44. --uvLen;
  45. }
  46. if (Nat.Gte(len, u, v))
  47. {
  48. Nat.SubFrom(len, v, u);
  49. Debug.Assert((u[0] & 1) == 0);
  50. ac += Nat.SubFrom(len, b, a) - bc;
  51. InversionStep(p, u, uvLen, a, ref ac);
  52. if (Nat.IsOne(len, u))
  53. {
  54. InversionResult(p, ac, a, z);
  55. return;
  56. }
  57. }
  58. else
  59. {
  60. Nat.SubFrom(len, u, v);
  61. Debug.Assert((v[0] & 1) == 0);
  62. bc += Nat.SubFrom(len, a, b) - ac;
  63. InversionStep(p, v, uvLen, b, ref bc);
  64. if (Nat.IsOne(len, v))
  65. {
  66. InversionResult(p, bc, b, z);
  67. return;
  68. }
  69. }
  70. }
  71. }
  72. public static uint[] Random(uint[] p)
  73. {
  74. int len = p.Length;
  75. uint[] s = Nat.Create(len);
  76. uint m = p[len - 1];
  77. m |= m >> 1;
  78. m |= m >> 2;
  79. m |= m >> 4;
  80. m |= m >> 8;
  81. m |= m >> 16;
  82. do
  83. {
  84. byte[] bytes = new byte[len << 2];
  85. RandomSource.NextBytes(bytes);
  86. Pack.BE_To_UInt32(bytes, 0, s);
  87. s[len - 1] &= m;
  88. }
  89. while (Nat.Gte(len, s, p));
  90. return s;
  91. }
  92. public static void Add(uint[] p, uint[] x, uint[] y, uint[] z)
  93. {
  94. int len = p.Length;
  95. uint c = Nat.Add(len, x, y, z);
  96. if (c != 0)
  97. {
  98. Nat.SubFrom(len, p, z);
  99. }
  100. }
  101. public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z)
  102. {
  103. int len = p.Length;
  104. int c = Nat.Sub(len, x, y, z);
  105. if (c != 0)
  106. {
  107. Nat.AddTo(len, p, z);
  108. }
  109. }
  110. private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z)
  111. {
  112. if (ac < 0)
  113. {
  114. Nat.Add(p.Length, a, p, z);
  115. }
  116. else
  117. {
  118. Array.Copy(a, 0, z, 0, p.Length);
  119. }
  120. }
  121. private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc)
  122. {
  123. int len = p.Length;
  124. int count = 0;
  125. while (u[0] == 0)
  126. {
  127. Nat.ShiftDownWord(uLen, u, 0);
  128. count += 32;
  129. }
  130. {
  131. int zeroes = GetTrailingZeroes(u[0]);
  132. if (zeroes > 0)
  133. {
  134. Nat.ShiftDownBits(uLen, u, zeroes, 0);
  135. count += zeroes;
  136. }
  137. }
  138. for (int i = 0; i < count; ++i)
  139. {
  140. if ((x[0] & 1) != 0)
  141. {
  142. if (xc < 0)
  143. {
  144. xc += (int)Nat.AddTo(len, p, x);
  145. }
  146. else
  147. {
  148. xc += Nat.SubFrom(len, p, x);
  149. }
  150. }
  151. Debug.Assert(xc == 0 || xc == -1);
  152. Nat.ShiftDownBit(len, x, (uint)xc);
  153. }
  154. }
  155. private static int GetTrailingZeroes(uint x)
  156. {
  157. Debug.Assert(x != 0);
  158. int count = 0;
  159. while ((x & 1) == 0)
  160. {
  161. x >>= 1;
  162. ++count;
  163. }
  164. return count;
  165. }
  166. }
  167. }
  168. #pragma warning restore
  169. #endif