SecP256R1Field.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.Diagnostics;
  4. using Org.BouncyCastle.Math.Raw;
  5. namespace Org.BouncyCastle.Math.EC.Custom.Sec
  6. {
  7. internal class SecP256R1Field
  8. {
  9. // 2^256 - 2^224 + 2^192 + 2^96 - 1
  10. internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
  11. 0x00000001, 0xFFFFFFFF };
  12. internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
  13. 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE,
  14. 0x00000002, 0xFFFFFFFE };
  15. internal const uint P7 = 0xFFFFFFFF;
  16. internal const uint PExt15 = 0xFFFFFFFE;
  17. public static void Add(uint[] x, uint[] y, uint[] z)
  18. {
  19. uint c = Nat256.Add(x, y, z);
  20. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  21. {
  22. AddPInvTo(z);
  23. }
  24. }
  25. public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
  26. {
  27. uint c = Nat.Add(16, xx, yy, zz);
  28. if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt)))
  29. {
  30. Nat.SubFrom(16, PExt, zz);
  31. }
  32. }
  33. public static void AddOne(uint[] x, uint[] z)
  34. {
  35. uint c = Nat.Inc(8, x, z);
  36. if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  37. {
  38. AddPInvTo(z);
  39. }
  40. }
  41. public static uint[] FromBigInteger(BigInteger x)
  42. {
  43. uint[] z = Nat256.FromBigInteger(x);
  44. if (z[7] == P7 && Nat256.Gte(z, P))
  45. {
  46. Nat256.SubFrom(P, z);
  47. }
  48. return z;
  49. }
  50. public static void Half(uint[] x, uint[] z)
  51. {
  52. if ((x[0] & 1) == 0)
  53. {
  54. Nat.ShiftDownBit(8, x, 0, z);
  55. }
  56. else
  57. {
  58. uint c = Nat256.Add(x, P, z);
  59. Nat.ShiftDownBit(8, z, c);
  60. }
  61. }
  62. public static void Multiply(uint[] x, uint[] y, uint[] z)
  63. {
  64. uint[] tt = Nat256.CreateExt();
  65. Nat256.Mul(x, y, tt);
  66. Reduce(tt, z);
  67. }
  68. public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
  69. {
  70. uint c = Nat256.MulAddTo(x, y, zz);
  71. if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt)))
  72. {
  73. Nat.SubFrom(16, PExt, zz);
  74. }
  75. }
  76. public static void Negate(uint[] x, uint[] z)
  77. {
  78. if (Nat256.IsZero(x))
  79. {
  80. Nat256.Zero(z);
  81. }
  82. else
  83. {
  84. Nat256.Sub(P, x, z);
  85. }
  86. }
  87. public static void Reduce(uint[] xx, uint[] z)
  88. {
  89. long xx08 = xx[8], xx09 = xx[9], xx10 = xx[10], xx11 = xx[11];
  90. long xx12 = xx[12], xx13 = xx[13], xx14 = xx[14], xx15 = xx[15];
  91. const long n = 6;
  92. xx08 -= n;
  93. long t0 = xx08 + xx09;
  94. long t1 = xx09 + xx10;
  95. long t2 = xx10 + xx11 - xx15;
  96. long t3 = xx11 + xx12;
  97. long t4 = xx12 + xx13;
  98. long t5 = xx13 + xx14;
  99. long t6 = xx14 + xx15;
  100. long t7 = t5 - t0;
  101. long cc = 0;
  102. cc += (long)xx[0] - t3 - t7;
  103. z[0] = (uint)cc;
  104. cc >>= 32;
  105. cc += (long)xx[1] + t1 - t4 - t6;
  106. z[1] = (uint)cc;
  107. cc >>= 32;
  108. cc += (long)xx[2] + t2 - t5;
  109. z[2] = (uint)cc;
  110. cc >>= 32;
  111. cc += (long)xx[3] + (t3 << 1) + t7 - t6;
  112. z[3] = (uint)cc;
  113. cc >>= 32;
  114. cc += (long)xx[4] + (t4 << 1) + xx14 - t1;
  115. z[4] = (uint)cc;
  116. cc >>= 32;
  117. cc += (long)xx[5] + (t5 << 1) - t2;
  118. z[5] = (uint)cc;
  119. cc >>= 32;
  120. cc += (long)xx[6] + (t6 << 1) + t7;
  121. z[6] = (uint)cc;
  122. cc >>= 32;
  123. cc += (long)xx[7] + (xx15 << 1) + xx08 - t2 - t4;
  124. z[7] = (uint)cc;
  125. cc >>= 32;
  126. cc += n;
  127. Debug.Assert(cc >= 0);
  128. Reduce32((uint)cc, z);
  129. }
  130. public static void Reduce32(uint x, uint[] z)
  131. {
  132. long cc = 0;
  133. if (x != 0)
  134. {
  135. long xx08 = x;
  136. cc += (long)z[0] + xx08;
  137. z[0] = (uint)cc;
  138. cc >>= 32;
  139. if (cc != 0)
  140. {
  141. cc += (long)z[1];
  142. z[1] = (uint)cc;
  143. cc >>= 32;
  144. cc += (long)z[2];
  145. z[2] = (uint)cc;
  146. cc >>= 32;
  147. }
  148. cc += (long)z[3] - xx08;
  149. z[3] = (uint)cc;
  150. cc >>= 32;
  151. if (cc != 0)
  152. {
  153. cc += (long)z[4];
  154. z[4] = (uint)cc;
  155. cc >>= 32;
  156. cc += (long)z[5];
  157. z[5] = (uint)cc;
  158. cc >>= 32;
  159. }
  160. cc += (long)z[6] - xx08;
  161. z[6] = (uint)cc;
  162. cc >>= 32;
  163. cc += (long)z[7] + xx08;
  164. z[7] = (uint)cc;
  165. cc >>= 32;
  166. Debug.Assert(cc == 0 || cc == 1);
  167. }
  168. if (cc != 0 || (z[7] == P7 && Nat256.Gte(z, P)))
  169. {
  170. AddPInvTo(z);
  171. }
  172. }
  173. public static void Square(uint[] x, uint[] z)
  174. {
  175. uint[] tt = Nat256.CreateExt();
  176. Nat256.Square(x, tt);
  177. Reduce(tt, z);
  178. }
  179. public static void SquareN(uint[] x, int n, uint[] z)
  180. {
  181. Debug.Assert(n > 0);
  182. uint[] tt = Nat256.CreateExt();
  183. Nat256.Square(x, tt);
  184. Reduce(tt, z);
  185. while (--n > 0)
  186. {
  187. Nat256.Square(z, tt);
  188. Reduce(tt, z);
  189. }
  190. }
  191. public static void Subtract(uint[] x, uint[] y, uint[] z)
  192. {
  193. int c = Nat256.Sub(x, y, z);
  194. if (c != 0)
  195. {
  196. SubPInvFrom(z);
  197. }
  198. }
  199. public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
  200. {
  201. int c = Nat.Sub(16, xx, yy, zz);
  202. if (c != 0)
  203. {
  204. Nat.AddTo(16, PExt, zz);
  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. AddPInvTo(z);
  213. }
  214. }
  215. private static void AddPInvTo(uint[] z)
  216. {
  217. long c = (long)z[0] + 1;
  218. z[0] = (uint)c;
  219. c >>= 32;
  220. if (c != 0)
  221. {
  222. c += (long)z[1];
  223. z[1] = (uint)c;
  224. c >>= 32;
  225. c += (long)z[2];
  226. z[2] = (uint)c;
  227. c >>= 32;
  228. }
  229. c += (long)z[3] - 1;
  230. z[3] = (uint)c;
  231. c >>= 32;
  232. if (c != 0)
  233. {
  234. c += (long)z[4];
  235. z[4] = (uint)c;
  236. c >>= 32;
  237. c += (long)z[5];
  238. z[5] = (uint)c;
  239. c >>= 32;
  240. }
  241. c += (long)z[6] - 1;
  242. z[6] = (uint)c;
  243. c >>= 32;
  244. c += (long)z[7] + 1;
  245. z[7] = (uint)c;
  246. //c >>= 32;
  247. }
  248. private static void SubPInvFrom(uint[] z)
  249. {
  250. long c = (long)z[0] - 1;
  251. z[0] = (uint)c;
  252. c >>= 32;
  253. if (c != 0)
  254. {
  255. c += (long)z[1];
  256. z[1] = (uint)c;
  257. c >>= 32;
  258. c += (long)z[2];
  259. z[2] = (uint)c;
  260. c >>= 32;
  261. }
  262. c += (long)z[3] + 1;
  263. z[3] = (uint)c;
  264. c >>= 32;
  265. if (c != 0)
  266. {
  267. c += (long)z[4];
  268. z[4] = (uint)c;
  269. c >>= 32;
  270. c += (long)z[5];
  271. z[5] = (uint)c;
  272. c >>= 32;
  273. }
  274. c += (long)z[6] + 1;
  275. z[6] = (uint)c;
  276. c >>= 32;
  277. c += (long)z[7] - 1;
  278. z[7] = (uint)c;
  279. //c >>= 32;
  280. }
  281. }
  282. }
  283. #endif