Nat.cs 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  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. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw
  7. {
  8. internal abstract class Nat
  9. {
  10. private const ulong M = 0xFFFFFFFFUL;
  11. public static uint Add(int len, uint[] x, uint[] y, uint[] z)
  12. {
  13. ulong c = 0;
  14. for (int i = 0; i < len; ++i)
  15. {
  16. c += (ulong)x[i] + y[i];
  17. z[i] = (uint)c;
  18. c >>= 32;
  19. }
  20. return (uint)c;
  21. }
  22. public static uint Add33At(int len, uint x, uint[] z, int zPos)
  23. {
  24. Debug.Assert(zPos <= (len - 2));
  25. ulong c = (ulong)z[zPos + 0] + x;
  26. z[zPos + 0] = (uint)c;
  27. c >>= 32;
  28. c += (ulong)z[zPos + 1] + 1;
  29. z[zPos + 1] = (uint)c;
  30. c >>= 32;
  31. return c == 0 ? 0 : IncAt(len, z, zPos + 2);
  32. }
  33. public static uint Add33At(int len, uint x, uint[] z, int zOff, int zPos)
  34. {
  35. Debug.Assert(zPos <= (len - 2));
  36. ulong c = (ulong)z[zOff + zPos] + x;
  37. z[zOff + zPos] = (uint)c;
  38. c >>= 32;
  39. c += (ulong)z[zOff + zPos + 1] + 1;
  40. z[zOff + zPos + 1] = (uint)c;
  41. c >>= 32;
  42. return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2);
  43. }
  44. public static uint Add33To(int len, uint x, uint[] z)
  45. {
  46. ulong c = (ulong)z[0] + x;
  47. z[0] = (uint)c;
  48. c >>= 32;
  49. c += (ulong)z[1] + 1;
  50. z[1] = (uint)c;
  51. c >>= 32;
  52. return c == 0 ? 0 : IncAt(len, z, 2);
  53. }
  54. public static uint Add33To(int len, uint x, uint[] z, int zOff)
  55. {
  56. ulong c = (ulong)z[zOff + 0] + x;
  57. z[zOff + 0] = (uint)c;
  58. c >>= 32;
  59. c += (ulong)z[zOff + 1] + 1;
  60. z[zOff + 1] = (uint)c;
  61. c >>= 32;
  62. return c == 0 ? 0 : IncAt(len, z, zOff, 2);
  63. }
  64. public static uint AddBothTo(int len, uint[] x, uint[] y, uint[] z)
  65. {
  66. ulong c = 0;
  67. for (int i = 0; i < len; ++i)
  68. {
  69. c += (ulong)x[i] + y[i] + z[i];
  70. z[i] = (uint)c;
  71. c >>= 32;
  72. }
  73. return (uint)c;
  74. }
  75. public static uint AddBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  76. {
  77. ulong c = 0;
  78. for (int i = 0; i < len; ++i)
  79. {
  80. c += (ulong)x[xOff + i] + y[yOff + i] + z[zOff + i];
  81. z[zOff + i] = (uint)c;
  82. c >>= 32;
  83. }
  84. return (uint)c;
  85. }
  86. public static uint AddDWordAt(int len, ulong x, uint[] z, int zPos)
  87. {
  88. Debug.Assert(zPos <= (len - 2));
  89. ulong c = (ulong)z[zPos + 0] + (x & M);
  90. z[zPos + 0] = (uint)c;
  91. c >>= 32;
  92. c += (ulong)z[zPos + 1] + (x >> 32);
  93. z[zPos + 1] = (uint)c;
  94. c >>= 32;
  95. return c == 0 ? 0 : IncAt(len, z, zPos + 2);
  96. }
  97. public static uint AddDWordAt(int len, ulong x, uint[] z, int zOff, int zPos)
  98. {
  99. Debug.Assert(zPos <= (len - 2));
  100. ulong c = (ulong)z[zOff + zPos] + (x & M);
  101. z[zOff + zPos] = (uint)c;
  102. c >>= 32;
  103. c += (ulong)z[zOff + zPos + 1] + (x >> 32);
  104. z[zOff + zPos + 1] = (uint)c;
  105. c >>= 32;
  106. return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2);
  107. }
  108. public static uint AddDWordTo(int len, ulong x, uint[] z)
  109. {
  110. ulong c = (ulong)z[0] + (x & M);
  111. z[0] = (uint)c;
  112. c >>= 32;
  113. c += (ulong)z[1] + (x >> 32);
  114. z[1] = (uint)c;
  115. c >>= 32;
  116. return c == 0 ? 0 : IncAt(len, z, 2);
  117. }
  118. public static uint AddDWordTo(int len, ulong x, uint[] z, int zOff)
  119. {
  120. ulong c = (ulong)z[zOff + 0] + (x & M);
  121. z[zOff + 0] = (uint)c;
  122. c >>= 32;
  123. c += (ulong)z[zOff + 1] + (x >> 32);
  124. z[zOff + 1] = (uint)c;
  125. c >>= 32;
  126. return c == 0 ? 0 : IncAt(len, z, zOff, 2);
  127. }
  128. public static uint AddTo(int len, uint[] x, uint[] z)
  129. {
  130. ulong c = 0;
  131. for (int i = 0; i < len; ++i)
  132. {
  133. c += (ulong)x[i] + z[i];
  134. z[i] = (uint)c;
  135. c >>= 32;
  136. }
  137. return (uint)c;
  138. }
  139. public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff)
  140. {
  141. ulong c = 0;
  142. for (int i = 0; i < len; ++i)
  143. {
  144. c += (ulong)x[xOff + i] + z[zOff + i];
  145. z[zOff + i] = (uint)c;
  146. c >>= 32;
  147. }
  148. return (uint)c;
  149. }
  150. public static uint AddWordAt(int len, uint x, uint[] z, int zPos)
  151. {
  152. Debug.Assert(zPos <= (len - 1));
  153. ulong c = (ulong)x + z[zPos];
  154. z[zPos] = (uint)c;
  155. c >>= 32;
  156. return c == 0 ? 0 : IncAt(len, z, zPos + 1);
  157. }
  158. public static uint AddWordAt(int len, uint x, uint[] z, int zOff, int zPos)
  159. {
  160. Debug.Assert(zPos <= (len - 1));
  161. ulong c = (ulong)x + z[zOff + zPos];
  162. z[zOff + zPos] = (uint)c;
  163. c >>= 32;
  164. return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 1);
  165. }
  166. public static uint AddWordTo(int len, uint x, uint[] z)
  167. {
  168. ulong c = (ulong)x + z[0];
  169. z[0] = (uint)c;
  170. c >>= 32;
  171. return c == 0 ? 0 : IncAt(len, z, 1);
  172. }
  173. public static uint AddWordTo(int len, uint x, uint[] z, int zOff)
  174. {
  175. ulong c = (ulong)x + z[zOff];
  176. z[zOff] = (uint)c;
  177. c >>= 32;
  178. return c == 0 ? 0 : IncAt(len, z, zOff, 1);
  179. }
  180. public static uint CAdd(int len, int mask, uint[] x, uint[] y, uint[] z)
  181. {
  182. uint MASK = (uint)-(mask & 1);
  183. ulong c = 0;
  184. for (int i = 0; i < len; ++i)
  185. {
  186. c += (ulong)x[i] + (y[i] & MASK);
  187. z[i] = (uint)c;
  188. c >>= 32;
  189. }
  190. return (uint)c;
  191. }
  192. public static void CMov(int len, int mask, uint[] x, int xOff, uint[] z, int zOff)
  193. {
  194. uint MASK = (uint)-(mask & 1);
  195. for (int i = 0; i < len; ++i)
  196. {
  197. uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
  198. z_i ^= (diff & MASK);
  199. z[zOff + i] = z_i;
  200. }
  201. //uint half = 0x55555555U, rest = half << (-(int)MASK);
  202. //for (int i = 0; i < len; ++i)
  203. //{
  204. // uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
  205. // z_i ^= (diff & half);
  206. // z_i ^= (diff & rest);
  207. // z[zOff + i] = z_i;
  208. //}
  209. }
  210. public static void CMov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
  211. {
  212. mask = -(mask & 1);
  213. for (int i = 0; i < len; ++i)
  214. {
  215. int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
  216. z_i ^= (diff & mask);
  217. z[zOff + i] = z_i;
  218. }
  219. //int half = 0x55555555, rest = half << (-mask);
  220. //for (int i = 0; i < len; ++i)
  221. //{
  222. // int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
  223. // z_i ^= (diff & half);
  224. // z_i ^= (diff & rest);
  225. // z[zOff + i] = z_i;
  226. //}
  227. }
  228. public static void Copy(int len, uint[] x, uint[] z)
  229. {
  230. Array.Copy(x, 0, z, 0, len);
  231. }
  232. public static uint[] Copy(int len, uint[] x)
  233. {
  234. uint[] z = new uint[len];
  235. Array.Copy(x, 0, z, 0, len);
  236. return z;
  237. }
  238. public static void Copy(int len, uint[] x, int xOff, uint[] z, int zOff)
  239. {
  240. Array.Copy(x, xOff, z, zOff, len);
  241. }
  242. public static uint[] Create(int len)
  243. {
  244. return new uint[len];
  245. }
  246. public static ulong[] Create64(int len)
  247. {
  248. return new ulong[len];
  249. }
  250. public static int Dec(int len, uint[] z)
  251. {
  252. for (int i = 0; i < len; ++i)
  253. {
  254. if (--z[i] != uint.MaxValue)
  255. {
  256. return 0;
  257. }
  258. }
  259. return -1;
  260. }
  261. public static int Dec(int len, uint[] x, uint[] z)
  262. {
  263. int i = 0;
  264. while (i < len)
  265. {
  266. uint c = x[i] - 1;
  267. z[i] = c;
  268. ++i;
  269. if (c != uint.MaxValue)
  270. {
  271. while (i < len)
  272. {
  273. z[i] = x[i];
  274. ++i;
  275. }
  276. return 0;
  277. }
  278. }
  279. return -1;
  280. }
  281. public static int DecAt(int len, uint[] z, int zPos)
  282. {
  283. Debug.Assert(zPos <= len);
  284. for (int i = zPos; i < len; ++i)
  285. {
  286. if (--z[i] != uint.MaxValue)
  287. {
  288. return 0;
  289. }
  290. }
  291. return -1;
  292. }
  293. public static int DecAt(int len, uint[] z, int zOff, int zPos)
  294. {
  295. Debug.Assert(zPos <= len);
  296. for (int i = zPos; i < len; ++i)
  297. {
  298. if (--z[zOff + i] != uint.MaxValue)
  299. {
  300. return 0;
  301. }
  302. }
  303. return -1;
  304. }
  305. public static bool Eq(int len, uint[] x, uint[] y)
  306. {
  307. for (int i = len - 1; i >= 0; --i)
  308. {
  309. if (x[i] != y[i])
  310. {
  311. return false;
  312. }
  313. }
  314. return true;
  315. }
  316. public static uint[] FromBigInteger(int bits, BigInteger x)
  317. {
  318. if (x.SignValue < 0 || x.BitLength > bits)
  319. throw new ArgumentException();
  320. int len = (bits + 31) >> 5;
  321. uint[] z = Create(len);
  322. int i = 0;
  323. while (x.SignValue != 0)
  324. {
  325. z[i++] = (uint)x.IntValue;
  326. x = x.ShiftRight(32);
  327. }
  328. return z;
  329. }
  330. public static uint GetBit(uint[] x, int bit)
  331. {
  332. if (bit == 0)
  333. {
  334. return x[0] & 1;
  335. }
  336. int w = bit >> 5;
  337. if (w < 0 || w >= x.Length)
  338. {
  339. return 0;
  340. }
  341. int b = bit & 31;
  342. return (x[w] >> b) & 1;
  343. }
  344. public static bool Gte(int len, uint[] x, uint[] y)
  345. {
  346. for (int i = len - 1; i >= 0; --i)
  347. {
  348. uint x_i = x[i], y_i = y[i];
  349. if (x_i < y_i)
  350. return false;
  351. if (x_i > y_i)
  352. return true;
  353. }
  354. return true;
  355. }
  356. public static uint Inc(int len, uint[] z)
  357. {
  358. for (int i = 0; i < len; ++i)
  359. {
  360. if (++z[i] != uint.MinValue)
  361. {
  362. return 0;
  363. }
  364. }
  365. return 1;
  366. }
  367. public static uint Inc(int len, uint[] x, uint[] z)
  368. {
  369. int i = 0;
  370. while (i < len)
  371. {
  372. uint c = x[i] + 1;
  373. z[i] = c;
  374. ++i;
  375. if (c != 0)
  376. {
  377. while (i < len)
  378. {
  379. z[i] = x[i];
  380. ++i;
  381. }
  382. return 0;
  383. }
  384. }
  385. return 1;
  386. }
  387. public static uint IncAt(int len, uint[] z, int zPos)
  388. {
  389. Debug.Assert(zPos <= len);
  390. for (int i = zPos; i < len; ++i)
  391. {
  392. if (++z[i] != uint.MinValue)
  393. {
  394. return 0;
  395. }
  396. }
  397. return 1;
  398. }
  399. public static uint IncAt(int len, uint[] z, int zOff, int zPos)
  400. {
  401. Debug.Assert(zPos <= len);
  402. for (int i = zPos; i < len; ++i)
  403. {
  404. if (++z[zOff + i] != uint.MinValue)
  405. {
  406. return 0;
  407. }
  408. }
  409. return 1;
  410. }
  411. public static bool IsOne(int len, uint[] x)
  412. {
  413. if (x[0] != 1)
  414. {
  415. return false;
  416. }
  417. for (int i = 1; i < len; ++i)
  418. {
  419. if (x[i] != 0)
  420. {
  421. return false;
  422. }
  423. }
  424. return true;
  425. }
  426. public static bool IsZero(int len, uint[] x)
  427. {
  428. if (x[0] != 0)
  429. {
  430. return false;
  431. }
  432. for (int i = 1; i < len; ++i)
  433. {
  434. if (x[i] != 0)
  435. {
  436. return false;
  437. }
  438. }
  439. return true;
  440. }
  441. public static void Mul(int len, uint[] x, uint[] y, uint[] zz)
  442. {
  443. zz[len] = MulWord(len, x[0], y, zz);
  444. for (int i = 1; i < len; ++i)
  445. {
  446. zz[i + len] = MulWordAddTo(len, x[i], y, 0, zz, i);
  447. }
  448. }
  449. public static void Mul(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
  450. {
  451. zz[zzOff + len] = MulWord(len, x[xOff], y, yOff, zz, zzOff);
  452. for (int i = 1; i < len; ++i)
  453. {
  454. zz[zzOff + i + len] = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i);
  455. }
  456. }
  457. public static void Mul(uint[] x, int xOff, int xLen, uint[] y, int yOff, int yLen, uint[] zz, int zzOff)
  458. {
  459. zz[zzOff + yLen] = MulWord(yLen, x[xOff], y, yOff, zz, zzOff);
  460. for (int i = 1; i < xLen; ++i)
  461. {
  462. zz[zzOff + i + yLen] = MulWordAddTo(yLen, x[xOff + i], y, yOff, zz, zzOff + i);
  463. }
  464. }
  465. public static uint MulAddTo(int len, uint[] x, uint[] y, uint[] zz)
  466. {
  467. ulong zc = 0;
  468. for (int i = 0; i < len; ++i)
  469. {
  470. ulong c = MulWordAddTo(len, x[i], y, 0, zz, i) & M;
  471. c += zc + (zz[i + len] & M);
  472. zz[i + len] = (uint)c;
  473. zc = c >> 32;
  474. }
  475. return (uint)zc;
  476. }
  477. public static uint MulAddTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff)
  478. {
  479. ulong zc = 0;
  480. for (int i = 0; i < len; ++i)
  481. {
  482. ulong c = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
  483. c += zc + (zz[zzOff + len] & M);
  484. zz[zzOff + len] = (uint)c;
  485. zc = c >> 32;
  486. ++zzOff;
  487. }
  488. return (uint)zc;
  489. }
  490. public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff)
  491. {
  492. ulong c = 0, aVal = (ulong)a, bVal = (ulong)b;
  493. int i = 0;
  494. do
  495. {
  496. c += aVal * x[i] + bVal * y[i] + z[zOff + i];
  497. z[zOff + i] = (uint)c;
  498. c >>= 32;
  499. }
  500. while (++i < len);
  501. return (uint)c;
  502. }
  503. public static uint MulWord(int len, uint x, uint[] y, uint[] z)
  504. {
  505. ulong c = 0, xVal = (ulong)x;
  506. int i = 0;
  507. do
  508. {
  509. c += xVal * y[i];
  510. z[i] = (uint)c;
  511. c >>= 32;
  512. }
  513. while (++i < len);
  514. return (uint)c;
  515. }
  516. public static uint MulWord(int len, uint x, uint[] y, int yOff, uint[] z, int zOff)
  517. {
  518. ulong c = 0, xVal = (ulong)x;
  519. int i = 0;
  520. do
  521. {
  522. c += xVal * y[yOff + i];
  523. z[zOff + i] = (uint)c;
  524. c >>= 32;
  525. }
  526. while (++i < len);
  527. return (uint)c;
  528. }
  529. public static uint MulWordAddTo(int len, uint x, uint[] y, int yOff, uint[] z, int zOff)
  530. {
  531. ulong c = 0, xVal = (ulong)x;
  532. int i = 0;
  533. do
  534. {
  535. c += xVal * y[yOff + i] + z[zOff + i];
  536. z[zOff + i] = (uint)c;
  537. c >>= 32;
  538. }
  539. while (++i < len);
  540. return (uint)c;
  541. }
  542. public static uint MulWordDwordAddAt(int len, uint x, ulong y, uint[] z, int zPos)
  543. {
  544. Debug.Assert(zPos <= (len - 3));
  545. ulong c = 0, xVal = (ulong)x;
  546. c += xVal * (uint)y + z[zPos + 0];
  547. z[zPos + 0] = (uint)c;
  548. c >>= 32;
  549. c += xVal * (y >> 32) + z[zPos + 1];
  550. z[zPos + 1] = (uint)c;
  551. c >>= 32;
  552. c += (ulong)z[zPos + 2];
  553. z[zPos + 2] = (uint)c;
  554. c >>= 32;
  555. return c == 0 ? 0 : IncAt(len, z, zPos + 3);
  556. }
  557. public static uint ShiftDownBit(int len, uint[] z, uint c)
  558. {
  559. int i = len;
  560. while (--i >= 0)
  561. {
  562. uint next = z[i];
  563. z[i] = (next >> 1) | (c << 31);
  564. c = next;
  565. }
  566. return c << 31;
  567. }
  568. public static uint ShiftDownBit(int len, uint[] z, int zOff, uint c)
  569. {
  570. int i = len;
  571. while (--i >= 0)
  572. {
  573. uint next = z[zOff + i];
  574. z[zOff + i] = (next >> 1) | (c << 31);
  575. c = next;
  576. }
  577. return c << 31;
  578. }
  579. public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z)
  580. {
  581. int i = len;
  582. while (--i >= 0)
  583. {
  584. uint next = x[i];
  585. z[i] = (next >> 1) | (c << 31);
  586. c = next;
  587. }
  588. return c << 31;
  589. }
  590. public static uint ShiftDownBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff)
  591. {
  592. int i = len;
  593. while (--i >= 0)
  594. {
  595. uint next = x[xOff + i];
  596. z[zOff + i] = (next >> 1) | (c << 31);
  597. c = next;
  598. }
  599. return c << 31;
  600. }
  601. public static uint ShiftDownBits(int len, uint[] z, int bits, uint c)
  602. {
  603. Debug.Assert(bits > 0 && bits < 32);
  604. int i = len;
  605. while (--i >= 0)
  606. {
  607. uint next = z[i];
  608. z[i] = (next >> bits) | (c << -bits);
  609. c = next;
  610. }
  611. return c << -bits;
  612. }
  613. public static uint ShiftDownBits(int len, uint[] z, int zOff, int bits, uint c)
  614. {
  615. Debug.Assert(bits > 0 && bits < 32);
  616. int i = len;
  617. while (--i >= 0)
  618. {
  619. uint next = z[zOff + i];
  620. z[zOff + i] = (next >> bits) | (c << -bits);
  621. c = next;
  622. }
  623. return c << -bits;
  624. }
  625. public static uint ShiftDownBits(int len, uint[] x, int bits, uint c, uint[] z)
  626. {
  627. Debug.Assert(bits > 0 && bits < 32);
  628. int i = len;
  629. while (--i >= 0)
  630. {
  631. uint next = x[i];
  632. z[i] = (next >> bits) | (c << -bits);
  633. c = next;
  634. }
  635. return c << -bits;
  636. }
  637. public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff)
  638. {
  639. Debug.Assert(bits > 0 && bits < 32);
  640. int i = len;
  641. while (--i >= 0)
  642. {
  643. uint next = x[xOff + i];
  644. z[zOff + i] = (next >> bits) | (c << -bits);
  645. c = next;
  646. }
  647. return c << -bits;
  648. }
  649. public static uint ShiftDownWord(int len, uint[] z, uint c)
  650. {
  651. int i = len;
  652. while (--i >= 0)
  653. {
  654. uint next = z[i];
  655. z[i] = c;
  656. c = next;
  657. }
  658. return c;
  659. }
  660. public static uint ShiftUpBit(int len, uint[] z, uint c)
  661. {
  662. for (int i = 0; i < len; ++i)
  663. {
  664. uint next = z[i];
  665. z[i] = (next << 1) | (c >> 31);
  666. c = next;
  667. }
  668. return c >> 31;
  669. }
  670. public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c)
  671. {
  672. for (int i = 0; i < len; ++i)
  673. {
  674. uint next = z[zOff + i];
  675. z[zOff + i] = (next << 1) | (c >> 31);
  676. c = next;
  677. }
  678. return c >> 31;
  679. }
  680. public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z)
  681. {
  682. for (int i = 0; i < len; ++i)
  683. {
  684. uint next = x[i];
  685. z[i] = (next << 1) | (c >> 31);
  686. c = next;
  687. }
  688. return c >> 31;
  689. }
  690. public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff)
  691. {
  692. for (int i = 0; i < len; ++i)
  693. {
  694. uint next = x[xOff + i];
  695. z[zOff + i] = (next << 1) | (c >> 31);
  696. c = next;
  697. }
  698. return c >> 31;
  699. }
  700. public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff)
  701. {
  702. for (int i = 0; i < len; ++i)
  703. {
  704. ulong next = x[xOff + i];
  705. z[zOff + i] = (next << 1) | (c >> 63);
  706. c = next;
  707. }
  708. return c >> 63;
  709. }
  710. public static uint ShiftUpBits(int len, uint[] z, int bits, uint c)
  711. {
  712. Debug.Assert(bits > 0 && bits < 32);
  713. for (int i = 0; i < len; ++i)
  714. {
  715. uint next = z[i];
  716. z[i] = (next << bits) | (c >> -bits);
  717. c = next;
  718. }
  719. return c >> -bits;
  720. }
  721. public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c)
  722. {
  723. Debug.Assert(bits > 0 && bits < 32);
  724. for (int i = 0; i < len; ++i)
  725. {
  726. uint next = z[zOff + i];
  727. z[zOff + i] = (next << bits) | (c >> -bits);
  728. c = next;
  729. }
  730. return c >> -bits;
  731. }
  732. public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c)
  733. {
  734. Debug.Assert(bits > 0 && bits < 64);
  735. for (int i = 0; i < len; ++i)
  736. {
  737. ulong next = z[zOff + i];
  738. z[zOff + i] = (next << bits) | (c >> -bits);
  739. c = next;
  740. }
  741. return c >> -bits;
  742. }
  743. public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z)
  744. {
  745. Debug.Assert(bits > 0 && bits < 32);
  746. for (int i = 0; i < len; ++i)
  747. {
  748. uint next = x[i];
  749. z[i] = (next << bits) | (c >> -bits);
  750. c = next;
  751. }
  752. return c >> -bits;
  753. }
  754. public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff)
  755. {
  756. Debug.Assert(bits > 0 && bits < 32);
  757. for (int i = 0; i < len; ++i)
  758. {
  759. uint next = x[xOff + i];
  760. z[zOff + i] = (next << bits) | (c >> -bits);
  761. c = next;
  762. }
  763. return c >> -bits;
  764. }
  765. public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff)
  766. {
  767. Debug.Assert(bits > 0 && bits < 64);
  768. for (int i = 0; i < len; ++i)
  769. {
  770. ulong next = x[xOff + i];
  771. z[zOff + i] = (next << bits) | (c >> -bits);
  772. c = next;
  773. }
  774. return c >> -bits;
  775. }
  776. public static void Square(int len, uint[] x, uint[] zz)
  777. {
  778. int extLen = len << 1;
  779. uint c = 0;
  780. int j = len, k = extLen;
  781. do
  782. {
  783. ulong xVal = (ulong)x[--j];
  784. ulong p = xVal * xVal;
  785. zz[--k] = (c << 31) | (uint)(p >> 33);
  786. zz[--k] = (uint)(p >> 1);
  787. c = (uint)p;
  788. }
  789. while (j > 0);
  790. for (int i = 1; i < len; ++i)
  791. {
  792. c = SquareWordAdd(x, i, zz);
  793. AddWordAt(extLen, c, zz, i << 1);
  794. }
  795. ShiftUpBit(extLen, zz, x[0] << 31);
  796. }
  797. public static void Square(int len, uint[] x, int xOff, uint[] zz, int zzOff)
  798. {
  799. int extLen = len << 1;
  800. uint c = 0;
  801. int j = len, k = extLen;
  802. do
  803. {
  804. ulong xVal = (ulong)x[xOff + --j];
  805. ulong p = xVal * xVal;
  806. zz[zzOff + --k] = (c << 31) | (uint)(p >> 33);
  807. zz[zzOff + --k] = (uint)(p >> 1);
  808. c = (uint)p;
  809. }
  810. while (j > 0);
  811. for (int i = 1; i < len; ++i)
  812. {
  813. c = SquareWordAdd(x, xOff, i, zz, zzOff);
  814. AddWordAt(extLen, c, zz, zzOff, i << 1);
  815. }
  816. ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
  817. }
  818. public static uint SquareWordAdd(uint[] x, int xPos, uint[] z)
  819. {
  820. ulong c = 0, xVal = (ulong)x[xPos];
  821. int i = 0;
  822. do
  823. {
  824. c += xVal * x[i] + z[xPos + i];
  825. z[xPos + i] = (uint)c;
  826. c >>= 32;
  827. }
  828. while (++i < xPos);
  829. return (uint)c;
  830. }
  831. public static uint SquareWordAdd(uint[] x, int xOff, int xPos, uint[] z, int zOff)
  832. {
  833. ulong c = 0, xVal = (ulong)x[xOff + xPos];
  834. int i = 0;
  835. do
  836. {
  837. c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
  838. z[xPos + zOff] = (uint)c;
  839. c >>= 32;
  840. ++zOff;
  841. }
  842. while (++i < xPos);
  843. return (uint)c;
  844. }
  845. public static int Sub(int len, uint[] x, uint[] y, uint[] z)
  846. {
  847. long c = 0;
  848. for (int i = 0; i < len; ++i)
  849. {
  850. c += (long)x[i] - y[i];
  851. z[i] = (uint)c;
  852. c >>= 32;
  853. }
  854. return (int)c;
  855. }
  856. public static int Sub(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  857. {
  858. long c = 0;
  859. for (int i = 0; i < len; ++i)
  860. {
  861. c += (long)x[xOff + i] - y[yOff + i];
  862. z[zOff + i] = (uint)c;
  863. c >>= 32;
  864. }
  865. return (int)c;
  866. }
  867. public static int Sub33At(int len, uint x, uint[] z, int zPos)
  868. {
  869. Debug.Assert(zPos <= (len - 2));
  870. long c = (long)z[zPos + 0] - x;
  871. z[zPos + 0] = (uint)c;
  872. c >>= 32;
  873. c += (long)z[zPos + 1] - 1;
  874. z[zPos + 1] = (uint)c;
  875. c >>= 32;
  876. return c == 0 ? 0 : DecAt(len, z, zPos + 2);
  877. }
  878. public static int Sub33At(int len, uint x, uint[] z, int zOff, int zPos)
  879. {
  880. Debug.Assert(zPos <= (len - 2));
  881. long c = (long)z[zOff + zPos] - x;
  882. z[zOff + zPos] = (uint)c;
  883. c >>= 32;
  884. c += (long)z[zOff + zPos + 1] - 1;
  885. z[zOff + zPos + 1] = (uint)c;
  886. c >>= 32;
  887. return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2);
  888. }
  889. public static int Sub33From(int len, uint x, uint[] z)
  890. {
  891. long c = (long)z[0] - x;
  892. z[0] = (uint)c;
  893. c >>= 32;
  894. c += (long)z[1] - 1;
  895. z[1] = (uint)c;
  896. c >>= 32;
  897. return c == 0 ? 0 : DecAt(len, z, 2);
  898. }
  899. public static int Sub33From(int len, uint x, uint[] z, int zOff)
  900. {
  901. long c = (long)z[zOff + 0] - x;
  902. z[zOff + 0] = (uint)c;
  903. c >>= 32;
  904. c += (long)z[zOff + 1] - 1;
  905. z[zOff + 1] = (uint)c;
  906. c >>= 32;
  907. return c == 0 ? 0 : DecAt(len, z, zOff, 2);
  908. }
  909. public static int SubBothFrom(int len, uint[] x, uint[] y, uint[] z)
  910. {
  911. long c = 0;
  912. for (int i = 0; i < len; ++i)
  913. {
  914. c += (long)z[i] - x[i] - y[i];
  915. z[i] = (uint)c;
  916. c >>= 32;
  917. }
  918. return (int)c;
  919. }
  920. public static int SubBothFrom(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff)
  921. {
  922. long c = 0;
  923. for (int i = 0; i < len; ++i)
  924. {
  925. c += (long)z[zOff + i] - x[xOff + i] - y[yOff + i];
  926. z[zOff + i] = (uint)c;
  927. c >>= 32;
  928. }
  929. return (int)c;
  930. }
  931. public static int SubDWordAt(int len, ulong x, uint[] z, int zPos)
  932. {
  933. Debug.Assert(zPos <= (len - 2));
  934. long c = (long)z[zPos + 0] - (long)(x & M);
  935. z[zPos + 0] = (uint)c;
  936. c >>= 32;
  937. c += (long)z[zPos + 1] - (long)(x >> 32);
  938. z[zPos + 1] = (uint)c;
  939. c >>= 32;
  940. return c == 0 ? 0 : DecAt(len, z, zPos + 2);
  941. }
  942. public static int SubDWordAt(int len, ulong x, uint[] z, int zOff, int zPos)
  943. {
  944. Debug.Assert(zPos <= (len - 2));
  945. long c = (long)z[zOff + zPos] - (long)(x & M);
  946. z[zOff + zPos] = (uint)c;
  947. c >>= 32;
  948. c += (long)z[zOff + zPos + 1] - (long)(x >> 32);
  949. z[zOff + zPos + 1] = (uint)c;
  950. c >>= 32;
  951. return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2);
  952. }
  953. public static int SubDWordFrom(int len, ulong x, uint[] z)
  954. {
  955. long c = (long)z[0] - (long)(x & M);
  956. z[0] = (uint)c;
  957. c >>= 32;
  958. c += (long)z[1] - (long)(x >> 32);
  959. z[1] = (uint)c;
  960. c >>= 32;
  961. return c == 0 ? 0 : DecAt(len, z, 2);
  962. }
  963. public static int SubDWordFrom(int len, ulong x, uint[] z, int zOff)
  964. {
  965. long c = (long)z[zOff + 0] - (long)(x & M);
  966. z[zOff + 0] = (uint)c;
  967. c >>= 32;
  968. c += (long)z[zOff + 1] - (long)(x >> 32);
  969. z[zOff + 1] = (uint)c;
  970. c >>= 32;
  971. return c == 0 ? 0 : DecAt(len, z, zOff, 2);
  972. }
  973. public static int SubFrom(int len, uint[] x, uint[] z)
  974. {
  975. long c = 0;
  976. for (int i = 0; i < len; ++i)
  977. {
  978. c += (long)z[i] - x[i];
  979. z[i] = (uint)c;
  980. c >>= 32;
  981. }
  982. return (int)c;
  983. }
  984. public static int SubFrom(int len, uint[] x, int xOff, uint[] z, int zOff)
  985. {
  986. long c = 0;
  987. for (int i = 0; i < len; ++i)
  988. {
  989. c += (long)z[zOff + i] - x[xOff + i];
  990. z[zOff + i] = (uint)c;
  991. c >>= 32;
  992. }
  993. return (int)c;
  994. }
  995. public static int SubWordAt(int len, uint x, uint[] z, int zPos)
  996. {
  997. Debug.Assert(zPos <= (len - 1));
  998. long c = (long)z[zPos] - x;
  999. z[zPos] = (uint)c;
  1000. c >>= 32;
  1001. return c == 0 ? 0 : DecAt(len, z, zPos + 1);
  1002. }
  1003. public static int SubWordAt(int len, uint x, uint[] z, int zOff, int zPos)
  1004. {
  1005. Debug.Assert(zPos <= (len - 1));
  1006. long c = (long)z[zOff + zPos] - x;
  1007. z[zOff + zPos] = (uint)c;
  1008. c >>= 32;
  1009. return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 1);
  1010. }
  1011. public static int SubWordFrom(int len, uint x, uint[] z)
  1012. {
  1013. long c = (long)z[0] - x;
  1014. z[0] = (uint)c;
  1015. c >>= 32;
  1016. return c == 0 ? 0 : DecAt(len, z, 1);
  1017. }
  1018. public static int SubWordFrom(int len, uint x, uint[] z, int zOff)
  1019. {
  1020. long c = (long)z[zOff + 0] - x;
  1021. z[zOff + 0] = (uint)c;
  1022. c >>= 32;
  1023. return c == 0 ? 0 : DecAt(len, z, zOff, 1);
  1024. }
  1025. public static BigInteger ToBigInteger(int len, uint[] x)
  1026. {
  1027. byte[] bs = new byte[len << 2];
  1028. for (int i = 0; i < len; ++i)
  1029. {
  1030. uint x_i = x[i];
  1031. if (x_i != 0)
  1032. {
  1033. Pack.UInt32_To_BE(x_i, bs, (len - 1 - i) << 2);
  1034. }
  1035. }
  1036. return new BigInteger(1, bs);
  1037. }
  1038. public static void Zero(int len, uint[] z)
  1039. {
  1040. for (int i = 0; i < len; ++i)
  1041. {
  1042. z[i] = 0;
  1043. }
  1044. }
  1045. }
  1046. }
  1047. #pragma warning restore
  1048. #endif