SecP256K1Field.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Diagnostics;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  8. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
  9. {
  10. internal class SecP256K1Field
  11. {
  12. // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
  13. internal static readonly uint[] P = new uint[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  14. 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
  15. private static readonly uint[] PExt = new uint[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000,
  16. 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  17. 0xFFFFFFFF, 0xFFFFFFFF };
  18. private static readonly uint[] PExtInv = new uint[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF,
  19. 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 };
  20. private const uint P7 = 0xFFFFFFFF;
  21. private const uint PExt15 = 0xFFFFFFFF;
  22. private const uint PInv33 = 0x3D1;
  23. public static void Add(uint[] x, uint[] y, uint[] z)
  24. {
  25. uint c = Nat256.Add(x, y, z);
  26. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  27. {
  28. Nat.Add33To(8, PInv33, z);
  29. }
  30. }
  31. public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
  32. {
  33. uint c = Nat.Add(16, xx, yy, zz);
  34. if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt)))
  35. {
  36. if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
  37. {
  38. Nat.IncAt(16, zz, PExtInv.Length);
  39. }
  40. }
  41. }
  42. public static void AddOne(uint[] x, uint[] z)
  43. {
  44. uint c = Nat.Inc(8, x, z);
  45. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  46. {
  47. Nat.Add33To(8, PInv33, z);
  48. }
  49. }
  50. public static uint[] FromBigInteger(BigInteger x)
  51. {
  52. uint[] z = Nat.FromBigInteger(256, x);
  53. if (z[7] == P7 && Nat256.Gte(z, P))
  54. {
  55. Nat256.SubFrom(P, z);
  56. }
  57. return z;
  58. }
  59. public static void Half(uint[] x, uint[] z)
  60. {
  61. if ((x[0] & 1) == 0)
  62. {
  63. Nat.ShiftDownBit(8, x, 0, z);
  64. }
  65. else
  66. {
  67. uint c = Nat256.Add(x, P, z);
  68. Nat.ShiftDownBit(8, z, c);
  69. }
  70. }
  71. public static void Inv(uint[] x, uint[] z)
  72. {
  73. Mod.CheckedModOddInverse(P, x, z);
  74. }
  75. public static int IsZero(uint[] x)
  76. {
  77. uint d = 0;
  78. for (int i = 0; i < 8; ++i)
  79. {
  80. d |= x[i];
  81. }
  82. d = (d >> 1) | (d & 1);
  83. return ((int)d - 1) >> 31;
  84. }
  85. public static void Multiply(uint[] x, uint[] y, uint[] z)
  86. {
  87. uint[] tt = Nat256.CreateExt();
  88. Nat256.Mul(x, y, tt);
  89. Reduce(tt, z);
  90. }
  91. public static void Multiply(uint[] x, uint[] y, uint[] z, uint[] tt)
  92. {
  93. Nat256.Mul(x, y, tt);
  94. Reduce(tt, z);
  95. }
  96. public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
  97. {
  98. uint c = Nat256.MulAddTo(x, y, zz);
  99. if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt)))
  100. {
  101. if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
  102. {
  103. Nat.IncAt(16, zz, PExtInv.Length);
  104. }
  105. }
  106. }
  107. public static void Negate(uint[] x, uint[] z)
  108. {
  109. if (0 != IsZero(x))
  110. {
  111. Nat256.Sub(P, P, z);
  112. }
  113. else
  114. {
  115. Nat256.Sub(P, x, z);
  116. }
  117. }
  118. public static void Random(SecureRandom r, uint[] z)
  119. {
  120. byte[] bb = new byte[8 * 4];
  121. do
  122. {
  123. r.NextBytes(bb);
  124. Pack.LE_To_UInt32(bb, 0, z, 0, 8);
  125. }
  126. while (0 == Nat.LessThan(8, z, P));
  127. }
  128. public static void RandomMult(SecureRandom r, uint[] z)
  129. {
  130. do
  131. {
  132. Random(r, z);
  133. }
  134. while (0 != IsZero(z));
  135. }
  136. public static void Reduce(uint[] xx, uint[] z)
  137. {
  138. ulong cc = Nat256.Mul33Add(PInv33, xx, 8, xx, 0, z, 0);
  139. uint c = Nat256.Mul33DWordAdd(PInv33, cc, z, 0);
  140. Debug.Assert(c == 0 || c == 1);
  141. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  142. {
  143. Nat.Add33To(8, PInv33, z);
  144. }
  145. }
  146. public static void Reduce32(uint x, uint[] z)
  147. {
  148. if ((x != 0 && Nat256.Mul33WordAdd(PInv33, x, z, 0) != 0)
  149. || (z[7] == P7 && Nat256.Gte(z, P)))
  150. {
  151. Nat.Add33To(8, PInv33, z);
  152. }
  153. }
  154. public static void Square(uint[] x, uint[] z)
  155. {
  156. uint[] tt = Nat256.CreateExt();
  157. Nat256.Square(x, tt);
  158. Reduce(tt, z);
  159. }
  160. public static void Square(uint[] x, uint[] z, uint[] tt)
  161. {
  162. Nat256.Square(x, tt);
  163. Reduce(tt, z);
  164. }
  165. public static void SquareN(uint[] x, int n, uint[] z)
  166. {
  167. Debug.Assert(n > 0);
  168. uint[] tt = Nat256.CreateExt();
  169. Nat256.Square(x, tt);
  170. Reduce(tt, z);
  171. while (--n > 0)
  172. {
  173. Nat256.Square(z, tt);
  174. Reduce(tt, z);
  175. }
  176. }
  177. public static void SquareN(uint[] x, int n, uint[] z, uint[] tt)
  178. {
  179. Debug.Assert(n > 0);
  180. Nat256.Square(x, tt);
  181. Reduce(tt, z);
  182. while (--n > 0)
  183. {
  184. Nat256.Square(z, tt);
  185. Reduce(tt, z);
  186. }
  187. }
  188. public static void Subtract(uint[] x, uint[] y, uint[] z)
  189. {
  190. int c = Nat256.Sub(x, y, z);
  191. if (c != 0)
  192. {
  193. Nat.Sub33From(8, PInv33, z);
  194. }
  195. }
  196. public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
  197. {
  198. int c = Nat.Sub(16, xx, yy, zz);
  199. if (c != 0)
  200. {
  201. if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
  202. {
  203. Nat.DecAt(16, zz, PExtInv.Length);
  204. }
  205. }
  206. }
  207. public static void Twice(uint[] x, uint[] z)
  208. {
  209. uint c = Nat.ShiftUpBit(8, x, 0, z);
  210. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  211. {
  212. Nat.Add33To(8, PInv33, z);
  213. }
  214. }
  215. }
  216. }
  217. #pragma warning restore
  218. #endif